mysql Pyramid + SQLAlchemy + Zope应用程序使用原始SQL返回错误结果

cwxwcias  于 2022-10-31  发布在  Mysql
关注(0)|答案(1)|浏览(98)

我有一个金字塔2.X + SQLAlchemy + Zope应用程序创建使用官方的CookieCutter。
有一个名为“schema_b.table_a”的表,其中包含0条记录。
在下面的视图中,count(*)应大于0,但返回0

  1. @view_config(route_name='home', renderer='myproject:templates/home.jinja2')
  2. def my_view(request):
  3. # Call external REST API. This uses HTTP requests. The API inserts in schema_b.table_a
  4. call_thirdparty_api()
  5. mark_changed(request.dbsession)
  6. sql = "SELECT count(*) FROM schema_b.table_a"
  7. total = request.dbsession.execute(sql).fetchone()
  8. print(total) # Total is 0
  9. return {}

另一方面,下列程式码会传回正确的count(*):

  1. @view_config(route_name='home', renderer='myproject:templates/home.jinja2')
  2. def my_view(request):
  3. engine = create_engine(request.registry.settings.get("sqlalchemy.url"), poolclass=NullPool)
  4. connection = engine.connect()
  5. # Call external REST API. This uses HTTP requests. The API inserts in table_a
  6. call_thirdparty_api()
  7. sql = "SELECT count(*) FROM schema_b.table_a"
  8. total = connection.execute(sql).fetchone()
  9. print(total) # Total is not 0
  10. connection.invalidate()
  11. engine.dispose()
  12. return {}

看起来request.session无法看到由外部REST API插入的数据,但我不清楚为什么或如何纠正它。

7vhp5slm

7vhp5slm1#

Pyramid和Zope提供了事务管理器,可以将事务扩展到数据库之外。在您的示例中,我认为当pyramid_tm包在服务器上接收到请求时,mysql中的一个事务就启动了,它们的文档说明:

由于mysql支持对事务进行一致的非阻塞读取,因此在调用request.dbsession.execute时,您查询的是事务开始时创建的数据库快照。当您使用普通的SQLAlchemy函数执行查询时,将创建一个新事务并返回预期的结果。
https://dev.mysql.com/doc/refman/8.0/en/innodb-consistent-read.html
在这种情况下,这是非常令人困惑的。但我必须承认,这是令人印象深刻的是,它似乎工作得很好。

相关问题