Pyramid dbsession总是会回滚

时间:2018-04-15 12:14:53

标签: python sqlalchemy pyramid

我正在尝试使用金字塔的事务管理器来提交更改。不幸的是,无论我做什么,每次都会回滚。

我尝试过这么简单:

def handle(conn):
    conn.execute('''ALTER TABLE ....''')

with bootstrap(sys.argv[1]) as env:
    with env['request'].tm:
        handle(env['request'].dbsession)

以及下拉到连接和创建显式事务:

def handle(conn):
    with conn.begin() as tran:
        conn.execute('''ALTER TABLE ....''')
        tran.commit()

with bootstrap(sys.argv[1]) as env:
    with env['request'].tm:
        handle(env['request'].dbsession.connection())

以及其他一些方法,但每次,我都会获得ROLLBACK而不是COMMIT

在第一种情况结束时进行简单提交会导致:

Error: Transaction must be committed using the transaction manager

我很遗憾sqlalchemy在这种情况下实际上做了什么 - 为什么我会通过回滚获得“成功”?我该怎么办?如果handle内有嵌套的显式事务,它会是什么样子?

1 个答案:

答案 0 :(得分:1)

正如ilja在评论中所说,正确的答案是,当您通过ORM操作直接操作连接而不是ORM会话时,zope.sqlalchemy无法知道是否你改变了什么。默认情况下,zope.sqlalchemy要求您使用ORM或标记手动更改的会话。

from zope.sqlalchemy import mark_changed

mark_changed(env['request'].dbsession)

或者,如果这是您的常见模式,那么您可以将zope.sqlalchemy配置为始终假设会话已更改,因此默认情况下会发出提交而不是回滚。

zope.sqlalchemy.register(..., initial_state='changed')

您的代码中已经有这样的调用,您只需要添加initial_state属性。