插入:filter和filter_by的区别
模块 | 语法 | ><(大于和小于)查询 | and_和or_查询 |
---|---|---|---|
filter_by() | 直接用属性名,比较用= | 不支持 | 不支持 |
filter() | 用类名.属性名,比较用== | 支持 | 支持 |
filter更强大
一 单表 创建表结构
users.py
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:admin@127.0.0.1:3306/sqlacm?charset=utf8",
# root 用户名 admin 密码 sqlacm 是数据库的名字
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:admin@127.0.0.1:3306/sqlacm?charset=utf8",
max_overflow=0, # 超过连接池大小外最多创建的连接
pool_size=5, # 连接池大小
pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
)
Base.metadata.drop_all(engine)
if __name__ == '__main__':
create_all()
drop_all()
具体的数据库的操作,增删改查
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from model import Users
# 引入自己写的model
engine = create_engine(
"mysql+pymysql://root:admin@127.0.0.1:3306/sqlacm?charset=utf8", # 用户:密码@../数据库名
max_overflow=0, # 超过连接池大小外最多创建的连接
pool_size=5, # 连接池大小
pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
)
SessionFactory = sessionmaker(bind=engine) # 实例化,SessionFactory,随意的命名
session = SessionFactory()
# -------------------加-------------------
# obj = Users(name='陈日天')
# session.add(obj)
# session.commit()
# 批量添加
# session.add_all([
# Users(name="斋藤飞鸟"),
# Users(name='井上苑子'),
# ])
# session.commit()
# --------------------查-------------------
# result = session.query(Users).all()
# for row in result:
# print(row.id, row.name)
# 指定字段, 返回列表套元组
# result = session.query(Users.id, Users.name).all()
# print(result)
# [(1, 'aki'), (2, 'desky')]
# result = session.query(Users).filter(Users.id >= 4)
# for row in result:
# print(row.id, row.name)
# --------------------删-------------------
# session.query(Users).filter(Users.id > 4).delete()
# session.commit()
# --------------------改-------------------
# session.query(Users).filter(Users.id == 8).update({Users.name: '大和田南那'})
# session.query(Users).filter(Users.id == 8).update({'name': '井上苑子'})
# session.query(Users).filter(Users.id == 8).update({'name': Users.name+"好きです"}, synchronize_session=False)
# 可以拼接, 后面的参数时拼接字符串,默认时True, 实现int的加
# session.query(Users).filter(Users.id == 8).update({'name': Users.id+1})
# session.commit()
# --------------------其他操作-------------------
# as 别名
# result = session.query(Users.id, Users.name.label('oname')).all()
# for row in result:
# print(row[1], row.id, row.oname) # row[1], 拿到是 USer.name
# between
# result = session.query(Users).filter(Users.id.between(1, 3), Users.name == 'aki').all()
# in 注意时 in_[]
# result = session.query(Users).filter(Users.id.in_([1, 3, 4])).all()
# result = session.query(Users).filter(~Users.id.in_([1, 3, 4])).all() # 不在
# 子查询
# result = session.query(Users).filter(Users.id.in_(session.query(Users.id).filter(Users.name == 'aki'))).all()
# and or 不写默认and, 要写的话,注意引用
from sqlalchemy import and_, or_
# result = session.query(Users).filter(and_(Users.id < 3, Users.name == 'aki')).all()
# result = session.query(Users).filter(or_(Users.id < 2, Users.name == 'aki')).all()
# result = session.query(Users).filter(
# or_(
# Users.id < 2,
# and_(Users.name == 'aki', Users.id > 3),
# Users.depart_id != ""
# )).all()
# 通配符
# result = session.query(Users).filter(Users.name.like('a%')).all()
# result = session.query(Users).filter(~Users.name.like('e%')).all()
# 切片
# result = session.query(Users)[1:2]
# 排序
# result = session.query(Users).order_by(Users.name.desc()).all()
# result = session.query(Users).order_by(Users.name.desc(), Users.id.asc()).all() # 先按降序拍,相同再升序
# 分组 注意要引人
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()
# for item in ret:
# print(item)
# 联表 union去重, union__all 不去重
# 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()
二 多表
一对多, 一对一
model.py
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',uselist=False)
# 反向查找的字段, 不会在数据库中创建字段, 加最后面的参数表示的时一对一
def __repr__(self):
return '<Users %r>' % self.name
# 创建表
def create_all():
engine = create_engine(
"mysql+pymysql://root:admin@127.0.0.1:3306/sqlacm?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:admin@127.0.0.1:3306/sqlacm?charset=utf8",
max_overflow=0, # 超过连接池大小外最多创建的连接
pool_size=5, # 连接池大小
pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
)
Base.metadata.drop_all(engine)
if __name__ == '__main__':
create_all()
# drop_all()
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from model import Users, Depart
engine = create_engine(
"mysql+pymysql://root:admin@127.0.0.1:3306/sqlacm?charset=utf8", # 用户:密码@../数据库名
max_overflow=0, # 超过连接池大小外最多创建的连接
pool_size=5, # 连接池大小
pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
)
SessionFactory = sessionmaker(bind=engine) # 实例化,SessionFactory,随意的命名
session = SessionFactory()
# join联表 默认inner join, souter=True left join
# ret = session.query(Users.id, Users.name, Depart.title).join(Depart, Users.depart_id == Depart.id).all()
# # ret= session.query(Users.id,Users.name,Depart.title).join(Depart,Users.depart_id == Depart.id,isouter=True)
# for row in ret:
# print(row.id, row.name, row.title)
# 通过relationship 外键字段正向跨表
# ret = session.query(Users).all()
# for row in ret:
# print(row.id, row.name, row.depart_id, row.dp.title)
# 反向 pers 反向的名字
# ret = session.query(Depart).filter(Depart.title == 'sas').first()
# for row in ret.pers:
# print(row.name)
# 通过relationship 正向添加数据
# a = Users(name='斋藤飞鸟', dp=Depart(title='后宫'))
# session.add(a)
# session.commit()
# 反向添加数据,User的depart_id 相同
# a = Depart(title='前台')
# a.pers = [Users(name='石原里美'), Users(name='新垣结衣'), Users(name='佐佐木希')]
# session.add(a)
# session.commit()
# session.close()
多对多,只能自己创建第三张表,和每张表的一对一
model.py
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 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)
student_id = Column(Integer, ForeignKey('student.id'))
course_id = Column(Integer, ForeignKey('course.id'))
__table_args__ = (
UniqueConstraint('student_id', 'course_id', name='aki'),
# Index('student_id', 'course_id', name='aki')
)
# 创建表
def create_all():
engine = create_engine(
"mysql+pymysql://root:admin@127.0.0.1:3306/sqlacm?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:admin@127.0.0.1:3306/sqlacm?charset=utf8",
max_overflow=0, # 超过连接池大小外最多创建的连接
pool_size=5, # 连接池大小
pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
)
Base.metadata.drop_all(engine)
if __name__ == '__main__':
create_all()
# drop_all()
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from model import Student,Course,Student2Course
engine = create_engine(
"mysql+pymysql://root:admin@127.0.0.1:3306/sqlacm?charset=utf8", # 用户:密码@../数据库名
max_overflow=0, # 超过连接池大小外最多创建的连接
pool_size=5, # 连接池大小
pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
)
SessionFactory = sessionmaker(bind=engine) # 实例化,SessionFactory,随意的命名
session = SessionFactory()
# 三表相联
# ret = session.query(Student2Course.id, Student.name, Course.title).\
# join(Student, Student2Course.student_id == Student.id).\
# join(Course, Student2Course.course_id == Course.id).order_by(Student2Course.id.asc())
# for row in ret:
# print(row)
# 通过relationship添加
# obj = Course(title='英语')
# obj.student_list = [Student(name='a'), Student(name='c')]
# session.add(obj)
# session.commit()
session.close()
三 多线程
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session
from models import Student,Course,Student2Course
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)
session = scoped_session(SessionFactory)
def task():
ret = session.query(Student).all()
# 将连接交还给连接池
session.remove()
from threading import Thread
for i in range(20):
t = Thread(target=task)
t.start()
四 执行原生sql
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from model import Student,Course,Student2Course
engine = create_engine(
"mysql+pymysql://root:admin@127.0.0.1:3306/sqlacm?charset=utf8", # 用户:密码@../数据库名
max_overflow=0, # 超过连接池大小外最多创建的连接
pool_size=5, # 连接池大小
pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
)
SessionFactory = sessionmaker(bind=engine) # 实例化,SessionFactory,随意的命名
session = SessionFactory()
# -----------查------------
cursor = session.execute('select * from users')
ret = cursor.fetchall()
print(ret)
# -----------加------------
# cursor = session.execute('INSERT INTO users(name) VALUES(:value)', params={"value": 'abc'})
# session.commit()
# 将连接交还给连接池
session.close()
Integer | int | 普通整数,一般是 32 位 |
SmallInteger | int | 取值范围小的整数,一般是 16 位 |
BigInteger | int 或 long | 不限制精度的整数 |
Float | float | |
Numeric | decimal.Decimal | 定点数 |
String | str | 变长字符串 |
Text | unicode | 变长 Unicode 字符串 |
UnicodeTex | unicode | 变长 Unicode 字符串,对较长或不限长度的字符串做了优化 |
Boolean | bool | |
Date | datetime.date | |
Time | datetime.time | |
DateTime | datetime.datetime | |
Interval | datetime.timedelta | 时间间隔 |
Enum | str | 一组字符串 |
LargeBinary | str | 二进制文件 |
primary_key | 如果设为 True,这列就是表的主键 |
unique | 如果设为 True,这列不允许出现重复的值 |
index | 如果设为 True,为这列创建索引,提升查询效率 |
nullable | 如果设为 True,这列允许使用空值;如果设为 False,这列不允许使用空值 |
default | 为这列定义默认值 |
backref | 在关系的另一个模型中添加反向引用 |
primaryjoin | 明确指定两个模型之间使用的联结条件。只在模棱两可的关系中需要指定 |
lazy | 指定如何加载相关记录。可选值有 select(首次访问时按需加载)、immediate(源对象加 载后就加载)、joined(加载记录,但使用联结)、subquery(立即加载,但使用子查询), noload(永不加载)和 dynamic(不加载记录,但提供加载记录的查询) |
uselist | 如果设为 Fales,不使用列表,而使用标量值 , 建立一对一关系,设置为False |
order_by | 指定关系中记录的排序方式 |
secondary | 指定多对多关系中关系表的名字 |
secondaryjoin | SQLAlchemy 无法自行决定时,指定多对多关系中的二级联结条件 |