session
操作
sqlalchemy 中使用 session
用于创建程序和数据库之间的会话,所有对象的载入和保存都需要通过 session
对象。
通过 sessionmaker
调用创建一个工厂,并关联 Engine
以确保每个 session
都可以使用该 Engine
连接资源:
from sqlalchemy.orm import sessionmaker
# 创建session
DbSession = sessionmaker(bind=engine) # 定义一个 Session 类,其中包括了引擎的信息
session = DbSession() # 通过 Session 类实例化一个 session 对象用来操作数据库
用上下文管理器及异常操作 session
这样出现异常可以回滚
with Session.begin() as session:
try:
session.add(some_object) # 执行对数据库的操作,但命令还在 session 中,没有发送到数据库
session.add(some_other_object)
except Exception as e:
session.rollback() # 如果出现异常吗,则进行回滚操作,虽然还没有对数据库进行操作,但 session 中的数据已经变了
raise
else:
session.commit() # 如果没有异常,则对数据库进行操作
session
中的常用操作方法
rollback
回滚操作,放弃之前所有事务commit
提交当前事务execute
执行 SQL 语句,并返回_engine.Result
对象,2.0 style 用这个进行查询操作scalar
相当于 session.execute().scalar()scalars
相当于 session.execute().scalars()close
关闭当前事务性资源和 ORM 对象expunge_all
删除 session 中所有 ORM 对象expunge
从 session 中删除 ORM 对象add
在 session 中放置一个 ORM 对象,和expunge
相对add_all
在 session 中放置一个 ORM 对象集合delete
将 ORM 对象标记为已删除get
基于给定的主键标识符返回 ORM 对象,如果找不到则返回None
flush
可以理解为预提交
commit
和 flush
的区别
- commit 操作比较好理解,就是提交一次事务 Transaction 操作。既然是提交一次事务操作,就包含了增删改的 SQL 操作。所以必然是 Session 通过 Connection 进行写磁盘 I/O 的操作。
- flush 不同的是,它并没有真正的执行事务 Transaction 的操作,而是更新了数据库的事务缓存。所以 flush 是会和数据库进行通信的。flush 操作告知数据库把事务操作缓存在数据库,直到数据库收到了 commit 操作之后才会真正将操作更新到磁盘中。
- flush方法会生成 Primary Key,所以哪怕 flush 之后并不进行 commit 操作,Primary Key 也还是会生成。所以下一次 Insert 一条记录时,Primary Key 会再次加1.
- 通常如果我们希望在 Commit 之前获取到待插入数据的自增主键,那我们可以在 commit 之前进行 flush 操作。这时 SQLAlchemy 的对象就会获取到数据库生成待对应数据行的主键值。
- Session 在进行查询时(查询操作之前)会进行一次 flush 操作。所以创建了对象,虽然并没有提交,但是紧接着进行 Query 操作也能在当前 Session 中查询到这个对象。
- flush 之后就能在当前 Session 中看到效果,而 commit 之后才能在其他 Session 中看到效果。