SQLAlchemy
orm(object relational mapping)是对象映射关系程序,通过orm将编程语言的对象模型和数据库的关系模型建立映射关系,这样我们在使用编程语言对数据库进行操作的时候可以直接使用编程语言的对象模型进行操作就可以了,而不用直接使用sql语言。
在Python中,最有名的ORM框架是SQLAlchemy。
创建表
models.py
from sqlalchemy import Table, Column, Integer, String, DATE, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
# 输入用户名、密码连接数据库
engine = create_engine("mysql+pymysql://root:mysqlroot@127.0.0.1/stu_manege", encoding='utf-8', echo=False)
# 生成ORM基类
Base = declarative_base()
# 用于多对多关联
class_m2m_stu = Table('class_m2m_stu', Base.metadata,
Column('class_id', Integer, ForeignKey('classes.class_id')),
Column('stu_id', Integer, ForeignKey('students.stu_id')),
)
class Class(Base):
__tablename__ = 'classes' # 表名
class_id = Column(Integer, primary_key=True, autoincrement=True)
class_name = Column(String(64), nullable=False)
class_method = Column(String(64))
student = relationship('Student', secondary=class_m2m_stu, backref='my_class')
# 通过my_class可以连接到Class类,通过student可以连接到Student类
def __repr__(self):
return self.class_name
# 返回Class类对象时,显示class_name
class Student(Base):
__tablename__ = 'students'
stu_id = Column(Integer, primary_key=True)
stu_name = Column(String(32), nullable=False)
def __repr__(self):
return self.stu_name
Base.metadata.create_all(engine) # 创建表结构
插入数据
from sqlalchemy.orm import sessionmaker
import models
Session_class = sessionmaker(bind=models.engine) # 创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例
session = Session_class() # 生成session实例
stu1 = models.Student(stu_id=100000001, stu_name='tom')
stu2 = models.Student(stu_id=100000002, stu_name='jerry')
cla1 = models.Class(class_name='python第一期', class_method='python')
cla2 = models.Class(class_name='python第二期', class_method='python')
# 添加关联对象
cla1.student = [stu1, stu2]
cla2.student = [stu1]
# class_m2m_stu表会自动创建多条记录连接classes和students表
session.add_all([stu1, stu2, cla1, cla2]) # 将要创建的数据对象添加到session中
session.commit() # 提交
查询数据
import models
from sqlalchemy.orm import sessionmaker
Session_class = sessionmaker(bind=models.engine)
session = Session_class()
# 获取students表中 stu_id == user_id 的数据(对象),通过stu.my_class就可以获取与stu对象关联的Class类信息
stu = session.query(models.Student).filter(models.Student.stu_id == user_id).first()
# 获取students表中 stu_id > id 的所有数据(对象列表)
stu = session.query(models.Student).filter(models.Student.stu_id > id).all()
# 多条件查询、获取students表中 min_id < stu_id < max_id 的所有数据(对象列表)
stu = session.query(models.Student).filter(models.Student.stu_id > min_id).filter(models.Student.stu_id < max_id).all()
修改数据
import models
from sqlalchemy.orm import sessionmaker
Session_class = sessionmaker(bind=models.engine)
session = Session_class()
# 先查询数据
stu = session.query(models.Student).filter(models.Student.stu_id == user_id).first()
# 直接修改
stu.stu_name = 'new_name'
# 提交
session.commit()
回滚
在session.commit()
前进行session.rollback()
可以撤销之前的操作
使用session.add()
添加数据后,数据会储存在session
中,这时session.rollback()
可以清除之前添加的数据。
统计和分组
# 统计students表中姓名以't'开头的学生数量
session.query(models.Student).filter(models.Student.name.like("t%")).count()
# 以学生姓名分组,并计数
from sqlalchemy import func
print(session.query(func.count(Student.stu_name),Student.stu_name).group_by(Student.stu_name).all() )
外键
只需建表时,在相关数据列声明stu_id = Column(Integer, ForeignKey('Student.stu_id'))
多对一
当一张表中有多个字段都关联了一张表时,如果这些字段relationship一样就分不清了:
billing_address = relationship("Address")
shipping_address = relationship("Address")
所以需要声明关联的外键:
billing_address = relationship("Address", foreign_keys=[billing_address_id])
shipping_address = relationship("Address", foreign_keys=[shipping_address_id])
这样就可以分清了
多对多
多对多的关系只需再引入一张表就可以表示,建表时需要额外建一张表:
class_m2m_stu = Table('class_m2m_stu', Base.metadata,
Column('class_id', Integer, ForeignKey('classes.class_id')),
Column('stu_id', Integer, ForeignKey('students.stu_id')),
)
插入数据时不用管这张表,只需这样表示就会把两张表连接起来
cla1.student = [stu1, stu2]
cla2.student = [stu1]
当删除数据时也不用管这张表,里面的关联关系数据会自动删除