add_finished_callback() 中没有事务 - 如何重新启动?
No transaction in add_finished_callback() - how can it be restarted?
使用 Pyramid 框架和 SQLAlchemy 作为数据库后端。我正在尝试将一些长 运行 HTTP GET 请求推迟到视图上的 add_finished_callback() ,允许它在视图呈现后呈现并更新数据库。然而,交易似乎在 Pyramid 运行回调时关闭:
Traceback (most recent call last):
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\waitress-1.4.3-py3.8.egg\waitress\channel.py", line 349, in service
task.service()
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\waitress-1.4.3-py3.8.egg\waitress\task.py", line 169, in service
self.execute()
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\waitress-1.4.3-py3.8.egg\waitress\task.py", line 439, in execute
app_iter = self.channel.server.application(environ, start_response)
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\pyramid-1.10.4-py3.8.egg\pyramid\router.py", line 270, in __call__
response = self.execution_policy(environ, self)
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\pyramid_retry-2.1.1-py3.8.egg\pyramid_retry\__init__.py", line 127, in retry_policy
response = router.invoke_request(request)
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\pyramid-1.10.4-py3.8.egg\pyramid\router.py", line 260, in invoke_request
request._process_finished_callbacks()
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\pyramid-1.10.4-py3.8.egg\pyramid\request.py", line 138, in _process_finished_callbacks
callback(self)
File "C:\Users\kenne\PycharmProjects\FCMS\FCMS\views\callback.py", line 25, in test_callback
print(f"Did some DB stuff, {ct.count()} and {cr.count()}")
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\query.py", line 3749, in count
return self.from_self(col).scalar()
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\query.py", line 3469, in scalar
ret = self.one()
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\query.py", line 3436, in one
ret = self.one_or_none()
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\query.py", line 3405, in one_or_none
ret = list(self)
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\query.py", line 3481, in __iter__
return self._execute_and_instances(context)
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\query.py", line 3502, in _execute_and_instances
conn = self._get_bind_args(
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\query.py", line 3517, in _get_bind_args
return fn(
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\query.py", line 3496, in _connection_from_session
conn = self.session.connection(**kw)
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\session.py", line 1138, in connection
return self._connection_for_bind(
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\session.py", line 1146, in _connection_for_bind
return self.transaction._connection_for_bind(
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\session.py", line 458, in _connection_for_bind
self.session.dispatch.after_begin(self.session, self, conn)
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\event\attr.py", line 322, in __call__
fn(*args, **kw)
File "c:\users\kenne\pycharmprojects\fcms\venv\lib\site-packages\zope.sqlalchemy-1.3-py3.8.egg\zope\sqlalchemy\datamanager.py", line 268, in after_begin
join_transaction(
File "c:\users\kenne\pycharmprojects\fcms\venv\lib\site-packages\zope.sqlalchemy-1.3-py3.8.egg\zope\sqlalchemy\datamanager.py", line 233, in join_transaction
DataManager(
File "c:\users\kenne\pycharmprojects\fcms\venv\lib\site-packages\zope.sqlalchemy-1.3-py3.8.egg\zope\sqlalchemy\datamanager.py", line 89, in __init__
transaction_manager.get().join(self)
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\transaction-3.0.0-py3.8.egg\transaction\_manager.py", line 91, in get
raise NoTransaction()
transaction.interfaces.NoTransaction
有谁知道在附加请求的 ZTM 中重新启动事务的好方法,还是应该使用在回调中实例化的单独数据库会话来完成?或者是否有理由在回调中根本不进行数据库处理?
add_finished_callback
运行s 在 tweens 之后,通常是清理发生的地方,并且是无序的,因此依赖数据库连接打开并不是一个好主意。
在请求的上下文中完成回调 运行 也毫无价值,因此您仍然在客户端执行时阻止将响应发送给客户端,因此将它们推迟到请求的后期实际上并没有给你带来太多好处。您必须将工作完全推迟到另一个线程才能更快地向客户端释放对 return 的响应,此时您肯定需要在该工作线程中打开一个新的数据库连接和事务。
如果您将 pyramid_tm 与您的数据库一起使用,则连接会在该补间的出口处关闭,之后访问 objects/database 通常会出现问题。
使用 Pyramid 框架和 SQLAlchemy 作为数据库后端。我正在尝试将一些长 运行 HTTP GET 请求推迟到视图上的 add_finished_callback() ,允许它在视图呈现后呈现并更新数据库。然而,交易似乎在 Pyramid 运行回调时关闭:
Traceback (most recent call last):
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\waitress-1.4.3-py3.8.egg\waitress\channel.py", line 349, in service
task.service()
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\waitress-1.4.3-py3.8.egg\waitress\task.py", line 169, in service
self.execute()
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\waitress-1.4.3-py3.8.egg\waitress\task.py", line 439, in execute
app_iter = self.channel.server.application(environ, start_response)
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\pyramid-1.10.4-py3.8.egg\pyramid\router.py", line 270, in __call__
response = self.execution_policy(environ, self)
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\pyramid_retry-2.1.1-py3.8.egg\pyramid_retry\__init__.py", line 127, in retry_policy
response = router.invoke_request(request)
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\pyramid-1.10.4-py3.8.egg\pyramid\router.py", line 260, in invoke_request
request._process_finished_callbacks()
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\pyramid-1.10.4-py3.8.egg\pyramid\request.py", line 138, in _process_finished_callbacks
callback(self)
File "C:\Users\kenne\PycharmProjects\FCMS\FCMS\views\callback.py", line 25, in test_callback
print(f"Did some DB stuff, {ct.count()} and {cr.count()}")
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\query.py", line 3749, in count
return self.from_self(col).scalar()
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\query.py", line 3469, in scalar
ret = self.one()
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\query.py", line 3436, in one
ret = self.one_or_none()
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\query.py", line 3405, in one_or_none
ret = list(self)
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\query.py", line 3481, in __iter__
return self._execute_and_instances(context)
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\query.py", line 3502, in _execute_and_instances
conn = self._get_bind_args(
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\query.py", line 3517, in _get_bind_args
return fn(
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\query.py", line 3496, in _connection_from_session
conn = self.session.connection(**kw)
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\session.py", line 1138, in connection
return self._connection_for_bind(
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\session.py", line 1146, in _connection_for_bind
return self.transaction._connection_for_bind(
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\orm\session.py", line 458, in _connection_for_bind
self.session.dispatch.after_begin(self.session, self, conn)
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\sqlalchemy-1.3.17-py3.8-win-amd64.egg\sqlalchemy\event\attr.py", line 322, in __call__
fn(*args, **kw)
File "c:\users\kenne\pycharmprojects\fcms\venv\lib\site-packages\zope.sqlalchemy-1.3-py3.8.egg\zope\sqlalchemy\datamanager.py", line 268, in after_begin
join_transaction(
File "c:\users\kenne\pycharmprojects\fcms\venv\lib\site-packages\zope.sqlalchemy-1.3-py3.8.egg\zope\sqlalchemy\datamanager.py", line 233, in join_transaction
DataManager(
File "c:\users\kenne\pycharmprojects\fcms\venv\lib\site-packages\zope.sqlalchemy-1.3-py3.8.egg\zope\sqlalchemy\datamanager.py", line 89, in __init__
transaction_manager.get().join(self)
File "C:\Users\kenne\PycharmProjects\FCMS\venv\lib\site-packages\transaction-3.0.0-py3.8.egg\transaction\_manager.py", line 91, in get
raise NoTransaction()
transaction.interfaces.NoTransaction
有谁知道在附加请求的 ZTM 中重新启动事务的好方法,还是应该使用在回调中实例化的单独数据库会话来完成?或者是否有理由在回调中根本不进行数据库处理?
add_finished_callback
运行s 在 tweens 之后,通常是清理发生的地方,并且是无序的,因此依赖数据库连接打开并不是一个好主意。
在请求的上下文中完成回调 运行 也毫无价值,因此您仍然在客户端执行时阻止将响应发送给客户端,因此将它们推迟到请求的后期实际上并没有给你带来太多好处。您必须将工作完全推迟到另一个线程才能更快地向客户端释放对 return 的响应,此时您肯定需要在该工作线程中打开一个新的数据库连接和事务。
如果您将 pyramid_tm 与您的数据库一起使用,则连接会在该补间的出口处关闭,之后访问 objects/database 通常会出现问题。