SQLAlchemy中flush()和commit()的区别是什么?

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

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

我想知道我是否使用了太多的commit()和没有足够的flush()调用 - 但是如果没有真正理解差异是什么,那就很难说了!

#1楼

正如@snapshoe所说

flush()将您的SQL语句发送到数据库

commit()提交事务。

session.autocommit == False :

如果设置autoflush == True commit()将调用flush() 。

当session.autocommit == True :

如果您尚未启动事务(您可能没有,因为您可能只使用此模式来避免手动管理事务),则无法调用commit() )。

在此模式下,必须调用flush()以保存ORM更改。 有效刷新也会提交您的数据。

#2楼

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

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

session.flush()将一系列操作传递给数据库(插入,更新,删除)。 数据库将它们维护为事务中的挂起操作。 在数据库收到当前事务的COMMIT(这就是session.commit()所做的事情session.commit()之前,更改不会永久保留到磁盘或对其他事务可见。

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

flush() 始终作为对commit() ( 1 )的调用的一部分进行调用。

当您使用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 []
2 []
3 [, ]
4 []