首页 > 解决方案 > Flask-Sqlalchemy Missing BEGIN 似乎导致会话不同步

问题描述

更新我的最后一个问题,请阅读这篇文章以获取背景信息。和我尝试过的这个reddit线程。我进行了进一步调查。

TL;DR 是对于某些请求,我似乎获得了旧数据。我通过发送一个 POST 来更新一个对象和几个 GET 来打印该对象的属性来测试这一点。通常反应很好,但我经常得到旧数据。在创建与其他对象有关系的对象时,这是一个大问题,如果由于某种原因外键对象不存在,则创建将失败。

例子:

format@pixel:~$ curl -X POST https://example.com/app/region/rename/5/Old
Success
format@pixel:~$ curl -X POST https://example.com/app/region/rename/5/New
Success
format@pixel:~$ for i in {1..25}; do  echo ; curl -X GET https://example.com/app/region/name/5/; done
New
New
New
New
New
New
Old
New
New
New
New
New
New
New
New
New
New
New
New
New
New
New
New
New
New

我打开了 SQLALCHEMY_ECHO 和 SQLALCHEMY_COMMIT_ON_TEARDOWN

app.config['SQLALCHEMY_ECHO'] = True
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True

并更改代码以打印更多信息。

当请求正确时,第一个日志片段是典型的。您可以在拆卸时看到隐含的 BEGIN 和 COMMIT。

[Tue Jul 24 17:49:23.217666 2018] [wsgi:error] [pid 27919:tid 139730801542912] --- Get Start ---
[Tue Jul 24 17:49:23.219964 2018] [wsgi:error] [pid 27919:tid 139730801542912] 2018-07-24 17:49:23,219 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
[Tue Jul 24 17:49:23.220053 2018] [wsgi:error] [pid 27919:tid 139730801542912] INFO:sqlalchemy.engine.base.Engine:BEGIN (implicit)
[Tue Jul 24 17:49:23.221282 2018] [wsgi:error] [pid 27919:tid 139730801542912] 2018-07-24 17:49:23,221 INFO sqlalchemy.engine.base.Engine SELECT region.id AS region_id, region.name AS region_name, region.north AS region_north, region.west AS region_west, region.south AS region_south, region.east AS region_east, region.coords AS region_coords 
[Tue Jul 24 17:49:23.221321 2018] [wsgi:error] [pid 27919:tid 139730801542912] FROM region 
[Tue Jul 24 17:49:23.221336 2018] [wsgi:error] [pid 27919:tid 139730801542912] WHERE region.id = %s
[Tue Jul 24 17:49:23.221356 2018] [wsgi:error] [pid 27919:tid 139730801542912] 
[Tue Jul 24 17:49:23.221414 2018] [wsgi:error] [pid 27919:tid 139730801542912] INFO:sqlalchemy.engine.base.Engine:SELECT region.id AS region_id, region.name AS region_name, region.north AS region_north, region.west AS region_west, region.south AS region_south, region.east AS region_east, region.coords AS region_coords 
[Tue Jul 24 17:49:23.221433 2018] [wsgi:error] [pid 27919:tid 139730801542912] FROM region 
[Tue Jul 24 17:49:23.221447 2018] [wsgi:error] [pid 27919:tid 139730801542912] WHERE region.id = %s
[Tue Jul 24 17:49:23.221465 2018] [wsgi:error] [pid 27919:tid 139730801542912] 
[Tue Jul 24 17:49:23.221683 2018] [wsgi:error] [pid 27919:tid 139730801542912] 2018-07-24 17:49:23,221 INFO sqlalchemy.engine.base.Engine (5,)
[Tue Jul 24 17:49:23.221767 2018] [wsgi:error] [pid 27919:tid 139730801542912] INFO:sqlalchemy.engine.base.Engine:(5,)
[Tue Jul 24 17:49:23.222922 2018] [wsgi:error] [pid 27919:tid 139730801542912] 2018-07-24 17:49:23.222868 New
[Tue Jul 24 17:49:23.222990 2018] [wsgi:error] [pid 27919:tid 139730801542912] --- Get End ---
[Tue Jul 24 17:49:23.224867 2018] [wsgi:error] [pid 27919:tid 139730801542912] 2018-07-24 17:49:23,224 INFO sqlalchemy.engine.base.Engine COMMIT
[Tue Jul 24 17:49:23.224946 2018] [wsgi:error] [pid 27919:tid 139730801542912] INFO:sqlalchemy.engine.base.Engine:COMMIT

当请求不正确时,下一个片段是典型的。您可以看到它正在执行与以前相同的 SELECT,但是没有 BEGIN 也没有 COMMIT。不确定这意味着什么或为什么会发生,但它让我相信问题出在 SQLAlchemy 或 MySQL 层。

[Tue Jul 24 17:49:23.288116 2018] [wsgi:error] [pid 27919:tid 139730654033664] --- Get Start ---
[Tue Jul 24 17:49:23.290049 2018] [wsgi:error] [pid 27919:tid 139730654033664] 2018-07-24 17:49:23,289 INFO sqlalchemy.engine.base.Engine SELECT region.id AS region_id, region.name AS region_name, region.north AS region_north, region.west AS region_west, region.south AS region_south, region.east AS region_east, region.coords AS region_coords 
[Tue Jul 24 17:49:23.290079 2018] [wsgi:error] [pid 27919:tid 139730654033664] FROM region 
[Tue Jul 24 17:49:23.290092 2018] [wsgi:error] [pid 27919:tid 139730654033664] WHERE region.id = %s
[Tue Jul 24 17:49:23.290109 2018] [wsgi:error] [pid 27919:tid 139730654033664] 
[Tue Jul 24 17:49:23.290168 2018] [wsgi:error] [pid 27919:tid 139730654033664] INFO:sqlalchemy.engine.base.Engine:SELECT region.id AS region_id, region.name AS region_name, region.north AS region_north, region.west AS region_west, region.south AS region_south, region.east AS region_east, region.coords AS region_coords 
[Tue Jul 24 17:49:23.290186 2018] [wsgi:error] [pid 27919:tid 139730654033664] FROM region 
[Tue Jul 24 17:49:23.290197 2018] [wsgi:error] [pid 27919:tid 139730654033664] WHERE region.id = %s
[Tue Jul 24 17:49:23.290214 2018] [wsgi:error] [pid 27919:tid 139730654033664] 
[Tue Jul 24 17:49:23.290422 2018] [wsgi:error] [pid 27919:tid 139730654033664] 2018-07-24 17:49:23,290 INFO sqlalchemy.engine.base.Engine (5,)
[Tue Jul 24 17:49:23.290499 2018] [wsgi:error] [pid 27919:tid 139730654033664] INFO:sqlalchemy.engine.base.Engine:(5,)
[Tue Jul 24 17:49:23.291567 2018] [wsgi:error] [pid 27919:tid 139730654033664] 2018-07-24 17:49:23.291529 @@OLD@@
[Tue Jul 24 17:49:23.291591 2018] [wsgi:error] [pid 27919:tid 139730654033664] --- Get End ---

您可以通过时间戳看到好的和坏的请求实际上是紧挨着的,在这个坏的请求之后也有几个好的请求,似乎没有韵律或理由。

我正在使用 mysqlclient 1.3.13、SQLAlchemy 1.2.10、Flask-SQLAlchemy 2.3.2 并在apt-get upgrade今天早些时候运行。

标签: pythonmysqlapacheflasksqlalchemy

解决方案


作为参考,如果有人发现这个线程有同样的问题,我解决了我的问题。

我的 Flask App 工厂函数app.app_context().push()在早期基于 Flask 教程时有剩余的行。在项目的重组过程中,这条线被遗漏了,问题自行解决了。不确定这条线为什么或如何会导致此问题,并且仅适用于某些但不是所有请求。


推荐阅读