我有一个金字塔2.X + SQLAlchemy + Zope应用程序创建使用官方的CookieCutter。
有一个名为“schema_b.table_a”的表,其中包含0条记录。
在下面的视图中,count(*)应大于0,但返回0
@view_config(route_name='home', renderer='myproject:templates/home.jinja2')
def my_view(request):
# Call external REST API. This uses HTTP requests. The API inserts in schema_b.table_a
call_thirdparty_api()
mark_changed(request.dbsession)
sql = "SELECT count(*) FROM schema_b.table_a"
total = request.dbsession.execute(sql).fetchone()
print(total) # Total is 0
return {}
另一方面,下列程式码会传回正确的count(*):
@view_config(route_name='home', renderer='myproject:templates/home.jinja2')
def my_view(request):
engine = create_engine(request.registry.settings.get("sqlalchemy.url"), poolclass=NullPool)
connection = engine.connect()
# Call external REST API. This uses HTTP requests. The API inserts in table_a
call_thirdparty_api()
sql = "SELECT count(*) FROM schema_b.table_a"
total = connection.execute(sql).fetchone()
print(total) # Total is not 0
connection.invalidate()
engine.dispose()
return {}
看起来request.session无法看到由外部REST API插入的数据,但我不清楚为什么或如何纠正它。
1条答案
按热度按时间7vhp5slm1#
Pyramid和Zope提供了事务管理器,可以将事务扩展到数据库之外。在您的示例中,我认为当pyramid_tm包在服务器上接收到请求时,mysql中的一个事务就启动了,它们的文档说明:
由于mysql支持对事务进行一致的非阻塞读取,因此在调用
request.dbsession.execute
时,您查询的是事务开始时创建的数据库快照。当您使用普通的SQLAlchemy函数执行查询时,将创建一个新事务并返回预期的结果。https://dev.mysql.com/doc/refman/8.0/en/innodb-consistent-read.html
在这种情况下,这是非常令人困惑的。但我必须承认,这是令人印象深刻的是,它似乎工作得很好。