我们在一些复杂的单元测试中使用sqlalchemy。在每次测试结束时,我们使用drop_all
完全拆除数据库。偶尔会有人忘记关闭嵌入在单元测试中的会话。然后,我们必须花费相当多的时间来弄清楚出了什么问题,并最终关闭sqlalchemy会话。
我们希望能够可靠地强制关闭所有与数据库的连接。我们尝试了session.close_all()
,但这并没有按照我的描述进行。
编辑: 下面是我们在进程挂起尝试删除数据库时看到的mysql进程列表。据推测,Id 285是违规的过程:
+-----+------+-----------------+----------+---------+------+---------------------------------+------------------------------+
| Id | User | Host | db | Command | Time | State | Info |
+-----+------+-----------------+----------+---------+------+---------------------------------+------------------------------+
| 172 | root | localhost | mydb | Query | 0 | init | show processlist |
| 285 | root | localhost:47147 | mydb | Sleep | 6 | | NULL |
| 289 | root | localhost:47152 | mydb | Query | 5 | Waiting for table metadata lock | DROP TABLE `mytable` |
+-----+------+-----------------+----------+---------+------+---------------------------------+------------------------------+
编辑:每个请求,我还包括事务日志:
------------
TRANSACTIONS
------------
Trx id counter 1144929
Purge done for trx's n:o < 1144827 undo n:o < 0 state: running but idle
History list length 398
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0, not started
MySQL thread id 37, OS thread handle 0x8f46bb40, query id 776 localhost root init
show engine innodb status
---TRANSACTION 0, not started
MySQL thread id 45, OS thread handle 0x8f2ceb40, query id 774 localhost 127.0.0.1 root Waiting for table metadata lock
DROP TABLE `mytable`
---TRANSACTION 1144823, ACTIVE 12 sec
MySQL thread id 41, OS thread handle 0x8f2ffb40, query id 595 localhost 127.0.0.1 root cleaning up
Trx read view will not see trx with id >= 1144824, sees < 1144824
答案 0 :(得分:1)
在烧瓶中,这应该可以解决问题:
@app.teardown_appcontext
def teardown_db(exception):
db.session.commit()
db.session.close()