sqlalchemy

插入: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()

常用的sqlacm类型
Integerint普通整数,一般是 32 位
SmallIntegerint取值范围小的整数,一般是 16 位
BigIntegerint 或 long不限制精度的整数
Floatfloat 
Numericdecimal.Decimal定点数
String str变长字符串
Textunicode变长 Unicode 字符串
UnicodeTexunicode变长 Unicode 字符串,对较长或不限长度的字符串做了优化 
Booleanbool 
Datedatetime.date 
Timedatetime.time 
DateTimedatetime.datetime 
Intervaldatetime.timedelta时间间隔
Enumstr一组字符串
LargeBinarystr二进制文件

 

列选项
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指定多对多关系中关系表的名字 
secondaryjoinSQLAlchemy 无法自行决定时,指定多对多关系中的二级联结条件

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值