Celery 和 SQLAlchemy - 此结果对象不返回行。已经自动关闭

新手上路,请多包涵

我有一个连接到 MySQL 数据库的芹菜项目。其中一个表定义如下:

 class MyQueues(Base):
    __tablename__ = 'accepted_queues'

    id = sa.Column(sa.Integer, primary_key=True)
    customer = sa.Column(sa.String(length=50), nullable=False)
    accepted = sa.Column(sa.Boolean, default=True, nullable=False)
    denied = sa.Column(sa.Boolean, default=True, nullable=False)

另外,在我的设置中

THREADS = 4

我被困在 code.py 的一个函数中:

 def load_accepted_queues(session, mode=None):

    #make query
    pool = session.query(MyQueues.customer, MyQueues.accepted, MyQueues.denied)

    #filter conditions
    if (mode == 'XXX'):
        pool = pool.filter_by(accepted=1)
    elif (mode == 'YYY'):
        pool = pool.filter_by(denied=1)
    elif (mode is None):
        pool = pool.filter(\
            sa.or_(MyQueues.accepted == 1, MyQueues.denied == 1)
            )

   #generate a dictionary with data
   for i in pool: #<---------- line 90 in the error
        l.update({i.customer: {'customer': i.customer, 'accepted': i.accepted, 'denied': i.denied}})

运行它时出现错误:

 [20130626 115343] Traceback (most recent call last):
  File "/home/me/code/processing/helpers.py", line 129, in wrapper
    ret_value = func(session, *args, **kwargs)
  File "/home/me/code/processing/test.py", line 90, in load_accepted_queues
    for i in pool: #generate a dictionary with data
  File "/home/me/envs/me/local/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2341, in instances
    fetch = cursor.fetchall()
  File "/home/me/envs/me/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 3205, in fetchall
    l = self.process_rows(self._fetchall_impl())
  File "/home/me/envs/me/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 3174, in _fetchall_impl
    self._non_result()
  File "/home/me/envs/me/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 3179, in _non_result
    "This result object does not return rows. "
ResourceClosedError: This result object does not return rows. It has been closed automatically

所以主要是部分

ResourceClosedError: This result object does not return rows. It has been closed automatically

有时还有这个错误:

DBAPIError: (Error) (, AssertionError(‘结果长度未请求长度:\n预期=1。实际=0。位置:21。数据长度:21’,)) ‘SELECT accepted_queues.customer AS accepted_queues_customer, accepted_queues.accepted AS accepted_queues_accepted , accepted_queues.denied AS accepted_queues_denied\nFROM accepted_queues\nWHERE accepted_queues.accepted = %s OR accepted_queues.denied = %s’ (1, 1)

我无法正确重现错误,因为它通常在处理大量数据时发生。我试图将 THREADS = 4 更改为 1 并且错误消失了。无论如何,这不是解决方案,因为我需要将线程数保留在 4 上。

另外,我对使用的必要性感到困惑

for i in pool: #<---------- line 90 in the error

或者

for i in pool.all(): #<---------- line 90 in the error

并且找不到合适的解释。

总之:有什么建议可以跳过这些困难吗?

原文由 fedorqui 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

总之:有什么建议可以跳过这些困难吗?

是的。您绝对 不能 同时在多个线程中使用 Session(或与该 Session 关联的任何对象)或 Connection,尤其是对于 MySQL-Python,其 DBAPI 连接非常线程不安全*。您必须组织您的应用程序,以便每个线程处理它自己的专用 MySQL-Python 连接(因此 SQLAlchemy 连接/会话/与该会话关联的对象),而不会泄漏到任何其他线程。

  • 编辑:或者,您可以使用互斥体来限制对 Session/Connection/DBAPI 连接的访问,一次只能访问其中一个线程,尽管这种情况不太常见,因为所需的高度锁定往往会破坏使用的目的首先是多个线程。

原文由 zzzeek 发布,翻译遵循 CC BY-SA 3.0 许可协议

我在使用 SQLAlchemy 查询 SQL-Server 过程时遇到了同样的错误。在我的例子中, SET NOCOUNT ON 添加到存储过程 解决了问题。

 ALTER PROCEDURE your_procedure_name
AS
BEGIN

    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for your procedure here
    SELECT *
    FROM your_table_name;

END;

查看 这篇文章 了解更多详情

原文由 Tabaraei 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题