SQLAlchemy

连接池

from sqlalchemy import create_engine
engine = create_engine(
    'mysql+pymysql://root:000000@192.168.30.161:3306/sqlalchemy_test?charset=utf8mb4',
    max_overflow=0,         # 超过联机池大小外最多创建的连接,-1表示无限制
    pool_size=5,            # 连接池大小, 0表示无限制
    pool_timeout=30,        # 池中没有线程,最多等待的时间(秒)
    pool_recycle=-1,        # 多久之后对线程池中的线程进行一次连接回收(重置)
)

单表

表结构

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, create_engine
from sqlalchemy import Integer, String, Boolean, DateTime
import datetime


Base = declarative_base()


class User(Base):
    __tablename__ = 'users'  # 数据库表名

    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(32), nullable=False, default='xxx')
    gender = Column(Boolean, nullable=False, default=True)
    date = Column(DateTime, onupdate=datetime.datetime.now, default=datetime.datetime.now, nullable=False)


if __name__ == '__main__':
    # 找到所有继承Base的类,在数据库中映射成表
    Base.metadata.create_all(engine)

    # 找到所有继承Base的类,在数据库中删除对应的表
    # Base.metadata.drop_all(engine)

增删改查

from models import User
from models import engine
from sqlalchemy.orm import sessionmaker
from datetime import timedelta
from datetime import datetime

SessionFactory = sessionmaker(bind=engine)

session = SessionFactory()


# 增
obj1 = User(name='xp')
obj2 = User(name='test')
obj3 = User(name='zhangshan')
session.add_all([obj1, obj2, obj3])           # session.add(对象) 增加一条数据
session.commit()


# 查
rest = session.query(User).all()
for row in rest:
    print(row.id, row.name, row.gender)

rest = session.query(User).filter(User.id >=1).first()
print(rest)

session.query(User).filter_by(name='xxx')   # filter(User.name=='xxx')


# 删
rest = session.query(User).filter(User.name=='def').delete()
session.commit()


# 改
session.query(User).filter(User.id == 3).update({User.name: 'aaa', User.gender: False})
session.commit()

session.query(User).filter(User.id == 3).update({'name': 'aaa', 'gender': False})
session.commit()

session.query(User).filter(User.id == 3).update({User.name: User.name+'xxx'}, synchronize_session=False)
session.commit()

ret = session.query(User).filter(User.id == 3).first()
ret.date += timedelta(days=3)
session.commit()


# 关闭连接
session.close()

其他常用操作

# 起别名
# ret = session.query(User.id, User.name.label('cname')).all()
# for item in ret:
#     print(item.cname)


# and
# session.query(User).filter(User.id > 1, User.name == 'xxx')


# between and
# session.query(User).filter(User.id.between(1, 3)).all()


# in, not in
# session.query(User).filter(User.id.in_([1, 2, 3]))
# session.query(User).filter(~User.id.in_([1, 2, 3]))  # not in


# 子查询
# session.query(User).filter(User.id.in_(session.query(User.id).filter(User.name == 'xxx')))


# from sqlalchemy import and_, or_, not_

# or
# session.query(User).filter(or_(User.id == 1, User.name == 'test')).all()

# or and
# session.query(User).filter(or_(User.id == 1, and_(User.id > 3, User.name == 'test')))

# not
# session.query(User).filter(not_(User.name=='abc'))


# 通配符
# session.query(User).filter(User.name.like('e%')).all()
# session.query(User).filter(~User.name.like('e%')).all()


# limit
# ret = session.query(User).filter(User.id>1).limit(2).all()


# 分组
# from sqlalchemy.sql import func
#
# ret = session.query(
#     func.max(User.id),
#     func.sum(User.id),
#     func.min(User.id),
#     func.group_concat(User.name)
# ).group_by(User.gender).all()
# print(ret)


# # having
# session.query(User).filter(User.id>1).having(User.gender==True)


# union union_all
# q1 = session.query(User)
# q2 = session.query(User)
# q1.union(q2).all()
# q1.union_all(q2)

一对多

表结构

from sqlalchemy import ForeignKey
from sqlalchemy.orm import relation
class User(Base):
    __tablename__ = 'users'  # 数据库表名

    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(32), nullable=False, default='xxx')
    depart_id = Column(Integer, ForeignKey('depart.id'))       # depart是表名,不是类名
	dp = relation('Depart', backref='user')					   # 建立关系

    
class Depart(Base):
    __tablename__ = 'depart'
    id = Column(Integer, primary_key=True, autoincrement=True)
    title = Column(String(32), nullable=False)

查询数据

# 默认根据ForeignKey连接
result = session.query(User, Depart).join(Depart).all()
# result = session.query(User, Depart).join(Depart, User.depart_id==Depart,id()).all()
for row in result:
    print(row[0].name, row[1].title)

# 外连接
query = session.query(User.name, Depart.title).join(Depart, isouter=True)
print(query)


# 直接跨表,正向查询
result = session.query(User).all()
for row in result:
    print(row.name, row.dp.title)
# 反向查询
result = session.query(Depart).filter(Depart.title == '开发').first()
for row in result.user:
    print(row.name, result.title)

增加数据

# 方式1
d1 = Depart(title='测试')
u1 = User(name='alex')
d1.user.append(u1)
session.add(d1)
session.commit()


# 方式2
d1 = Depart(title='测试')
u1 = User(name='alex')
u1.dp = d1
session.add(u1)
session.commit()

修改数据

depart_obj = session.query(Depart).filter(Depart.title=='测试').first()
session.query(User).filter(User.dp==depart_obj).update({User.name: 'test'})
session.commit()


depart_obj1 = session.query(Depart).filter(Depart.title=='运维').first()
depart_obj2 = session.query(Depart).filter(Depart.title=='开发').first()
session.query(User).filter(User.dp==depart_obj1).update({User.depart_id:depart_obj2.id})
session.commit()

多对多

from sqlalchemy import UniqueConstraint

class Student(Base):
    __tablename__ = 'student'
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(32), nullable=True)
    # secondary 是第三张表名
    course = relation('Course', secondary='student2course', backref='student')


class Course(Base):
    __tablename__ = 'course'
    id = Column(Integer, primary_key=True, autoincrement=True)
    title = Column(String(32), nullable=True)


class StudentToCourse(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='index_stu_cou'),
    )
s_obj = session.query(Student).filter(Student.name=='xxx').first()
c_obj_list = s_obj.course
for row in c_obj_list:
    print(row.title)

其他操作参考一对多

两种连接方式

方式一

from models import Student
from models import engine
from sqlalchemy.orm import sessionmaker
from threading import Thread

def task():
    Session = sessionmaker(bind=engine)
    session = Session()
    ret = session.query(Student).all()
    print(ret)
    session.close()

for i in range(20):
    Thread(target=task).start()

方式二(推荐)

from models import Student
from models import engine
from sqlalchemy.orm import sessionmaker, scoped_session
from threading import Thread

Session = sessionmaker(bind=engine)
session = scoped_session(Session)

def task():
    ret = session.query(Student).all()
    print(ret)
    session.remove()

for i in range(20):
    Thread(target=task).start()

执行原生SQL

cursor = session.execute('select * from student')
ret = cursor.fetchall()
print(ret)
cursor.close()

cursor = session.execute("insert into student(name) value(:v1)",params={"v1":"test"})
session.commit()
cursor.close()
print(cursor.lastrowid)         # 打印最后一个自增id

session.close()
conn = engine.raw_connection()
cursor = conn.cursor()
ret = cursor.execute("select * from student")
print(ret)
cursor.close()
conn.close()
posted @ 2020-06-07 20:59  _Otis  阅读(120)  评论(0编辑  收藏  举报