小编典典

SQLAlchemy:flush() 和 commit() 有什么区别?

all

flush()SQLAlchemy和SQLAlchemy之间有什么区别commit()

我已经阅读了文档,但并不明智 - 他们似乎假设了我没有的预先理​​解。

我对它们对内存使用的影响特别感兴趣。我正在从一系列文件(总共大约 500 万行)中将一些数据加载到数据库中,并且我的会话偶尔会失败 -
这是一个大型数据库和一台内存不多的机器。

我想知道我是否使用了太多commit()而没有足够的flush()调用 - 但如果没有真正了解区别是什么,很难说!


阅读 103

收藏
2022-03-09

共1个答案

小编典典

Session
对象基本上是对数据库进行更改(更新、插入、删除)的持续事务。这些操作在提交之前不会持久保存到数据库中(如果您的程序在会话中期事务中由于某种原因中止,则其中任何未提交的更改都将丢失)。

会话对象向 注册事务操作,但在被调用session.add()之前不会将它们传递给数据库。session.flush()

session.flush()向数据库传达一系列操作(插入、更新、删除)。数据库将它们作为事务中的待处理操作进行维护。在数据库接收到当前事务的
COMMIT 之前,这些更改不会永久保存在磁盘上,或者对其他事务可见(这就是这样session.commit()做的)。

session.commit()将这些更改提交(持久)到数据库。

flush()总是作为调用( 1 )
的一部分


调用。commit()

当您使用 Session 对象查询数据库时,查询将返回来自数据库和它所持有的未提交事务的已刷新部分的结果。默认情况下,Session
对象autoflush他们的操作,但这可以被禁用。

希望这个例子能更清楚地说明这一点:

#---
s = Session()

s.add(Foo('A')) # The Foo('A') object has been added to the session.
                # It has not been committed to the database yet,
                #   but is returned as part of a query.
print 1, s.query(Foo).all()
s.commit()

#---
s2 = Session()
s2.autoflush = False

s2.add(Foo('B'))
print 2, s2.query(Foo).all() # The Foo('B') object is *not* returned
                             #   as part of this query because it hasn't
                             #   been flushed yet.
s2.flush()                   # Now, Foo('B') is in the same state as
                             #   Foo('A') was above.
print 3, s2.query(Foo).all() 
s2.rollback()                # Foo('B') has not been committed, and rolling
                             #   back the session's transaction removes it
                             #   from the session.
print 4, s2.query(Foo).all()

#---
Output:
1 [<Foo('A')>]
2 [<Foo('A')>]
3 [<Foo('A')>, <Foo('B')>]
4 [<Foo('A')>]
2022-03-09