Сельдерей и 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 ('длина результата не просила длина:nExpected=1. Actual=0. Позиция: 21. Длина Данных: 21',)) 'Выберите accepted_queues.клиент как accepted_queues_customer, accepted_queues.принято как accepted_queues_accepted, accepted_queues.отклонено как accepted_queues_denied nFROM accepted_queues nWHERE accepted_queues.принято = %s или accepted_queues.denied = %s' (1, 1)

Я не могу воспроизвести errror должным образом, как это обычно происходит при обработке большого количества данных. Я пытался изменить THREADS = 4 to 1 и ошибки исчезли. Во всяком случае, это не решение, так как мне нужно количество потоков, которые будут сохранены на 4.

кроме того, я смущен необходимостью использовать

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

или

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

и не мог найти надлежащего объяснения этому.

все вместе: любые советуют пропустить эти трудности?

1 ответов


все вместе: любые советуют пропустить эти трудности?

да. ты абсолютно не может используйте сеанс (или любые объекты, которые связаны с этим сеансом) или соединение, в более чем одном потоке одновременно, особенно с MySQL-Python, чьи соединения DBAPI очень небезопасны для потока*. Вы должны организовать свое приложение так, чтобы каждый поток имел дело с собственным, выделенным соединением MySQL-Python (и, следовательно, SQLAlchemy Соединение / сеанс / объекты, связанные с этим сеансом) без утечки в любой другой поток.

  • Edit: кроме того, вы можете использовать мьютексы для ограничения доступа к сеансу/соединению/соединению DBAPI только к одному из этих потоков за раз, хотя это менее распространено, потому что высокая степень блокировки, необходимая, как правило, побеждает цель использования нескольких потоков в первую очередь.