SQLAlchemy使用介绍
SQLAlchemy is the Python SQL toolkit and Object Relational Mapper that gives application developers the full power and flexibility of SQL. SQLAlchemy provides a full suite of well known enterprise-level persistence patterns, designed for efficient and high-performing database access, adapted into a simple and Pythonic domain language.
SQLAlchemy 比Django的orm更接近原生sql的语法书写
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column
from sqlalchemy import Integer,String,Text,Date,DateTime
from sqlalchemy import create_engine Base = declarative_base() class Users(Base):
__tablename__ = 'users' id = Column(Integer, primary_key=True)
name = Column(String(32), index=True, nullable=False)
depart_id = Column(Integer) def create_all():
engine = create_engine(
"mysql+pymysql://root:123456@127.0.0.1:3306/s9day120?charset=utf8",
max_overflow=0, # 超过连接池大小外最多创建的连接
pool_size=5, # 连接池大小
pool_timeout=10, # 池中没有连接最多等待的时间,否则报错
pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
)
Base.metadata.create_all(engine) def drop_all():
engine = create_engine(
"mysql+pymysql://root:123456@127.0.0.1:3306/s9day120?charset=utf8",
max_overflow=0, # 超过连接池大小外最多创建的连接
pool_size=5, # 连接池大小
pool_timeout=10, # 池中没有连接最多等待的时间,否则报错
pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
)
Base.metadata.drop_all(engine) if __name__ == '__main__':
drop_all()
create_all() # 已经有表的话,不会重复创建
注意:SQLAlchemy本身创建表之后,不支持删除表中的字段,再次运行修改表结构的,需要借助第三方模块(靠生成migration文件)
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from models import Users engine = create_engine(
"mysql+pymysql://root:123456@127.0.0.1:3306/s9day120?charset=utf8",
max_overflow=0, # 超过连接池大小外最多创建的连接
pool_size=5, # 连接池大小
pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
)
SessionFactory = sessionmaker(bind=engine) # 根据Users类对users表进行增删改查
session = SessionFactory() # ############################## 基本增删改查 ###############################
# 1. 增加
obj = Users(name='alex')
session.add(obj)
session.commit() session.add_all([
Users(name='小东北'),
Users(name='龙泰')
])
session.commit() # 2. 查
result = session.query(Users).all()
for row in result:
print(row.id,row.name) result = session.query(Users).filter(Users.id >= 2)
for row in result:
print(row.id,row.name) result = session.query(Users).filter(Users.id >= 2).first()
print(result) # 3.删
session.query(Users).filter(Users.id >= 2).delete()
session.commit() # 4.改
session.query(Users).filter(Users.id == 4).update({Users.name:'东北'})
session.query(Users).filter(Users.id == 4).update({'name':'小东北'})
session.query(Users).filter(Users.id == 4).update({'name':Users.name+"DSB"},synchronize_session=False)
# synchronize_session 让Users.name+"DSB"变成字符串连接操作 session.commit()
session.close()
CRUD操作
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from models import Users engine = create_engine(
"mysql + pymysql://root:123456@127.0.0.1:3306/s9day120?charset=utf8",
max_overflow=0, # 超过连接池大小外最多创建的连接
pool_size=5, # 连接池大小
pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
)
SessionFactory = sessionmaker(bind=engine) # 根据Users类对users表进行增删改查
session = SessionFactory() # 1. 指定列
# select id,name as cname from users;
result = session.query(Users.id,Users.name.label('cname')).all()
for item in result:
print(item[0],item.id,item.cname) sql_query = session.query(Users.id,Users.name.label('cname')) # 查看sql语句 # 2. 默认条件and
session.query(Users).filter(Users.id > 1, Users.name == 'eric').all()
# 3. between
session.query(Users).filter(Users.id.between(1, 3), Users.name == 'eric').all()
# 4. in
session.query(Users).filter(Users.id.in_([1,3,4])).all()
session.query(Users).filter(~Users.id.in_([1,3,4])).all()
# 5. 子查询
session.query(Users).filter(Users.id.in_(session.query(Users.id).filter(Users.name=='eric'))).all()
# 6. and 和 or
from sqlalchemy import and_, or_
session.query(Users).filter(Users.id > 3, Users.name == 'eric').all()
session.query(Users).filter(and_(Users.id > 3, Users.name == 'eric')).all()
session.query(Users).filter(or_(Users.id < 2, Users.name == 'eric')).all()
session.query(Users).filter(
or_(
Users.id < 2,
and_(Users.name == 'eric', Users.id > 3),
Users.extra != ""
)).all() # 7. filter_by
session.query(Users).filter_by(name='ppp').all() # 内部还是转换成表达式,调用filter方法 # 8. 通配符
ret = session.query(Users).filter(Users.name.like('e%')).all()
ret = session.query(Users).filter(~Users.name.like('e%')).all() # 9. 切片
result = session.query(Users)[1:2] # 10.排序
ret = session.query(Users).order_by(Users.name.desc()).all()
ret = session.query(Users).order_by(Users.name.desc(), Users.id.asc()).all() # 11. group by
from sqlalchemy.sql import func ret = session.query(
Users.depart_id,
func.count(Users.id), # 指定按照什么来聚合,如果不指定则会按照默认底层配置来取,这样可能就不是我们想要的
).group_by(Users.depart_id).all()
for item in ret:
print(item) ret = session.query(
Users.depart_id,
func.count(Users.id),
).group_by(Users.depart_id).having(func.count(Users.id) >= 2).all() # having
for item in ret:
print(item) # 12.union 和 union all
"""
select id,name from users
UNION
select id,name from users;
"""
q1 = session.query(Users.name).filter(Users.id > 2)
q2 = session.query(Favor.caption).filter(Favor.nid < 2)
ret = q1.union(q2).all() q1 = session.query(Users.name).filter(Users.id > 2)
q2 = session.query(Favor.caption).filter(Favor.nid < 2)
ret = q1.union_all(q2).all() session.close()
查询,子查询,分组,通配符,逻辑运算,排序等操作
多表操作
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column
from sqlalchemy import Integer,String,Text,Date,DateTime,ForeignKey,UniqueConstraint, Index
from sqlalchemy import create_engine
from sqlalchemy.orm import relationship Base = declarative_base() class Depart(Base):
__tablename__ = 'depart'
id = Column(Integer, primary_key=True)
title = Column(String(32), index=True, nullable=False) class Users(Base):
__tablename__ = 'users' id = Column(Integer, primary_key=True)
name = Column(String(32), index=True, nullable=False)
depart_id = Column(Integer,ForeignKey("depart.id")) dp = relationship("Depart", backref='pers') class Student(Base):
__tablename__ = 'student'
id = Column(Integer, primary_key=True)
name = Column(String(32), index=True, nullable=False) course_list = relationship('Course', secondary='student2course', backref='student_list') class Course(Base):
__tablename__ = 'course'
id = Column(Integer, primary_key=True)
title = Column(String(32), index=True, nullable=False) class Student2Course(Base):
__tablename__ = 'student2course'
id = Column(Integer, primary_key=True, autoincrement=True)
student_id = Column(Integer, ForeignKey('student.id'))
course_id = Column(Integer, ForeignKey('course.id')) __table_args__ = (
UniqueConstraint('student_id', 'course_id', name='uix_stu_cou'), # 联合唯一索引
# Index('ix_id_name', 'name', 'extra'), # 联合索引
) def create_all():
engine = create_engine(
"mysql+pymysql://root:@127.0.0.1:3306/s9day120?charset=utf8",
max_overflow=0, # 超过连接池大小外最多创建的连接
pool_size=5, # 连接池大小
pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
) Base.metadata.create_all(engine) def drop_all():
engine = create_engine(
"mysql+pymysql://root:@127.0.0.1:3306/s9day120?charset=utf8",
max_overflow=0, # 超过连接池大小外最多创建的连接
pool_size=5, # 连接池大小
pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
)
Base.metadata.drop_all(engine) if __name__ == '__main__':
create_all()
表结构
# 查询
# 查询所有用户+所属部门名称
ret = session.query(Users.id,Users.name,Depart.title).join(Depart,Users.depart_id == Depart.id).all()
for row in ret:
print(row.id,row.name,row.title) # isouter默认是False,表示inner join
query = session.query(Users.id,Users.name,Depart.title).join(Depart,Users.depart_id == Depart.id,isouter=True)
print(query) # relation字段:查询所有用户+所属部门名称
ret = session.query(Users).all()
for row in ret:
print(row.id,row.name,row.depart_id,row.dp.title) # relation字段:查询销售部所有的人员
obj = session.query(Depart).filter(Depart.title == '销售').first()
for row in obj.pers:
print(row.id,row.name,obj.title) # 增加
# 创建一个名称叫:IT部门,再在该部门中添加一个员工:田硕
# 方式一:
d1 = Depart(title='IT')
session.add(d1)
session.commit() u1 = Users(name='田硕',depart_id=d1.id)
session.add(u1)
session.commit() # 方式二:
u1 = Users(name='田硕',dp=Depart(title='IT'))
session.add(u1)
session.commit() # 创建一个名称叫:王者荣耀,再在该部门中添加一个员工:龚林峰/长好梦/王爷们
d1 = Depart(title='王者荣耀')
d1.pers = [Users(name='龚林峰'),Users(name='长好梦'),Users(name='王爷们'),] # 批量添加
session.add(d1)
session.commit()
一对多操作
# 1. 录入数据
session.add_all([
Student(name='先用'),
Student(name='佳俊'),
Course(title='生物'),
Course(title='体育'),
])
session.commit() session.add_all([
Student2Course(student_id=2, course_id=1)
])
session.commit() # 2. 三张表关联
ret = session.query(Student2Course.id,Student.name,Course.title).join(Student,Student2Course.student_id==Student.id,isouter=True).join(Course,Student2Course.course_id==Course.id,isouter=True).order_by(Student2Course.id.asc())
for row in ret:
print(row) # 3. “先用”选的所有课
# 方式一
ret = session.query(Student2Course.id,Student.name,Course.title).outerjoin(Student,Student2Course.student_id==Student.id).outerjoin(Course,Student2Course.course_id==Course.id).filter(Student.name=='先用').order_by(Student2Course.id.asc()).all()
print(ret) # 方式二
obj = session.query(Student).filter(Student.name=='先用').first()
for item in obj.course_list:
print(item.title) # 4. 选了“生物”的所有人
ret = session.query(Course).filter(Course.title=='生物').first()
for row in ret.student_list:
print(row.name) # 5. 创建一个课程,创建2学生,两个学生选新创建的课程。
obj = Course(title='英语')
obj.student_list = [Student(name='为名'),Student(name='广宗')] session.add(obj)
session.commit()
多对多操作
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from models import Student,Course,Student2Course engine = create_engine(
"mysql+pymysql://root:@127.0.0.1:3306/s9day120?charset=utf8",
max_overflow=0, # 超过连接池大小外最多创建的连接
pool_size=5, # 连接池大小
pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
)
SessionFactory = sessionmaker(bind=engine) def task():
# 去连接池中获取一个连接,不能用全局变量中的连接
session = SessionFactory() ret = session.query(Student).all()
print(ret)
# 将连接交还给连接池
session.close() from threading import Thread for i in range(20):
t = Thread(target=task)
t.start()
多线程写法
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session
from models import Student engine = create_engine("mysql+pymysql://root:@127.0.0.1:3306/s9day120?charset=utf8", max_overflow=0, pool_size=5)
Session = sessionmaker(bind=engine) # 基于threading.local实现 """
# 线程安全,基于本地线程实现每个线程用同一个session
# 特殊的:scoped_session中有原来方法的Session中的一下方法: public_methods = (
'__contains__', '__iter__', 'add', 'add_all', 'begin', 'begin_nested',
'close', 'commit', 'connection', 'delete', 'execute', 'expire',
'expire_all', 'expunge', 'expunge_all', 'flush', 'get_bind',
'is_modified', 'bulk_save_objects', 'bulk_insert_mappings',
'bulk_update_mappings',
'merge', 'query', 'refresh', 'rollback',
'scalar'
)
"""
session = scoped_session(Session) def task():
ret = session.query(Student).all()
print(ret)
# 将连接交还给连接池
session.remove() from threading import Thread for i in range(10):
t = Thread(target=task)
t.start()
基于scoped_session实现线程安全,推荐写法
import time
import threading from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy import create_engine
from sqlalchemy.sql import text
from sqlalchemy.engine.result import ResultProxy
from models import Users engine = create_engine("mysql+pymysql://root:@127.0.0.1:3306/s9day120?charset=utf8", max_overflow=0, pool_size=5)
Session = sessionmaker(bind=engine) session = Session() # 查询
cursor = session.execute('select * from users')
result = cursor.fetchall()
print(result) # 添加
cursor = session.execute('insert into users(name) values(:value)',params={"value":'cpp'}) # 注意有:
session.commit()
print(cursor.lastrowid) # 方式二:
conn = engine.raw_connection()
cursor = conn.cursor()
cursor.execute(
"select * from users"
)
result = cursor.fetchall()
print(result) cursor.close()
conn.close() session.close()
原生SQL写法
class scoped_session(object): session_factory = None def __init__(self, session_factory, scopefunc=None):
self.session_factory = session_factory if scopefunc:
self.registry = ScopedRegistry(session_factory, scopefunc)
else:
self.registry = ThreadLocalRegistry(session_factory) def instrument(name): # 闭包
def do(self, *args, **kwargs):
return getattr(self.registry(), name)(*args, **kwargs)
return do class Session(_SessionClassMethods):
public_methods = (
'__contains__', '__iter__', 'add', 'add_all', 'begin', 'begin_nested',
'close', 'commit', 'connection', 'delete', 'execute', 'expire',
'expire_all', 'expunge', 'expunge_all', 'flush', 'get_bind',
'is_modified', 'bulk_save_objects', 'bulk_insert_mappings',
'bulk_update_mappings',
'merge', 'query', 'refresh', 'rollback',
'scalar') for meth in Session.public_methods: # 动态给scoped_session(Session) 设置方法
setattr(scoped_session, meth, instrument(meth)) class ThreadLocalRegistry(ScopedRegistry):
def __init__(self, createfunc):
self.createfunc = createfunc
self.registry = threading.local() def __call__(self):
try:
return self.registry.value
except AttributeError:
val = self.registry.value = self.createfunc() # self.createfunc就是 sessionmaker(bind=engine) 加()生成socket连接
return val
scoped_session源码分析
参考:
https://www.cnblogs.com/wupeiqi/articles/8259356.html
SQLAlchemy使用介绍的更多相关文章
- sqlalchemy orm介绍
ORM介绍 简解:用户会使用ORM时会直接访问对象,对象在通过ORM与数据库进行交互,不需要用户操作sql. 详解:orm英文全称object relational mapping,就是对象映射关系程 ...
- SQLALchemy之介绍,基本使用
一.介绍 SQLALchemy也是一个python的ORM框架,django内部的ORM框架只适用于django,而SQLALchemy适用于所有python的web框架 SQLAlchemy是一个基 ...
- sqlalchemy模块介绍、单表操作、一对多表操作、多对多表操作、flask集成.
今日内容概要 sqlalchemy介绍和快速使用 单表操作增删查改 一对多 多对多 flask集成 内容详细 1.sqlalchemy介绍和快速使用 # SQLAlchemy是一个基于 Python实 ...
- Python-12-MySQL & sqlalchemy ORM
MySQL MySQL相关文章这里不在赘述,想了解的点击下面的链接: >> MySQL安装 >> 数据库介绍 && MySQL基本使用 >> MyS ...
- Python操作Redis、Memcache、RabbitMQ、SQLAlchemy
Python操作 Redis.Memcache.RabbitMQ.SQLAlchemy redis介绍:redis是一个开源的,先进的KEY-VALUE存储,它通常被称为数据结构服务器,因为键可以包含 ...
- Day12 线程池、RabbitMQ和SQLAlchemy
1.with实现上下文管理 #!/usr/bin/env python# -*- coding: utf-8 -*-# Author: wanghuafeng #with实现上下文管理import c ...
- MySQL,sqlalchemy
Mariadb 数据库是一堆表的集合 主键 外键 索引 安装: Centos7 [root@host]# mysqladmin -u root password "new_password& ...
- python笔记-13 mysql与sqlalchemy
一.RDBMS relational database management system 关系型数据库引入 1.数据库的意义 更有效和合理的存储读取数据的一种方式 关系模型基础上的数据库 -> ...
- SQLAlchemy,flask-sqlalchemy
SQLAlchemy 1.介绍 SQLAlchemy是一个基于Python实现的ORM框架.该框架建立在 DB API之上,使用关系对象映射进行数据库操作,简言之便是:将类和对象转换成SQL,然后使用 ...
随机推荐
- python并发编程之IO阻塞基础知识点
IO模型 解决IO问题的方式方法 问题是:IO操作阻塞程序执行 解决的也仅仅是网络IO操作 一般数据传输经历的两个阶段,如图: IO阻塞模型分类: 阻塞IO 非阻塞IO 多路复用IO 异步IO(爬 ...
- pre的内容自动转行
使pre的内容自动换行(转) <pre> 元素可定义预格式化的文本.被包围在 pre 元素中的文本通常会保留空格和换行符.而文本也会呈现为等宽字体. <pre> 标签的一个常见 ...
- feed.snapdo.com 病毒
过程:安装破解office2013 使用破解工具 Microsoft toolkit 2.7 beta 1 关闭防火墙 浏览器被木马篡改:搜索引擎被篡改: 相关进程 bittorrent.exe 无 ...
- HFSS在进行仿真时端口与激励设置细则
最近发现在使用HFSS仿真天线时候在设置端口激励求解的时候,由于端口激励面积的大小和放置方式的不通最终的求解结果也有很多不同 在进行CPW结构的天线仿真中分别尝试了waveport 和lumpedpo ...
- JavaScript DOM 高级程序设计读书笔记二
响应用户操作和事件 事件就是操作检测与脚本执行的组合,或者基于检测到的操作类型在某个对象上调用事件侦听器(事件处理程序). 事件的类型 事件可以分为几种类型:对象事件,鼠标事件,键盘事件(只适用于do ...
- 20175209 《Java程序设计》第八周学习总结
20175209 <Java程序设计>第八周学习总结 一.教材知识点总结 1.泛型 1.泛型类声明: 格式 class People<E> People是泛型类名称 E是泛型列 ...
- Nginx location 匹配规则详解
语法规则 location [=|~|~*|^~] /uri/ { … } 模式 含义 location = /uri = 表示精确匹配,只有完全匹配上才能生效 location ^~ /uri ^~ ...
- python3 练手实例8 批量命名图片
#coding:utf-8 import os import tkinter as tk from tkinter import filedialog root = tk.Tk() root.with ...
- HTTP高并发调优小记
tomcat服务层 1.修改server.xml <Connector port="8088" protocol="HTTP/1.1" maxThread ...
- nautilus-open-terminal----在当前目录下打开终端
nautilus-open-terminal很有用的插件--鼠标右键打开终端 1.1 fedora安装 # yum -y install nautilus-open-terminal安装nautilu ...