Я использую SQLAlchemy в качестве ORM в приложении, которое я создавал в течение некоторого времени.
Пока что реализовать и использовать ORM было довольно безболезненно, однако для недавней функции, над которой я работаю, требуется реализация в стиле постоянных и распределенных очередей (list & worker), которую я встроил в MySQL и Python. .
Все это работало довольно хорошо, пока я не протестировал его в масштабируемой среде.
Я использовал блокировку на уровне строк InnoDB, чтобы гарантировать, что каждая строка читается только один раз, в то время как строка заблокирована, я обновляю значение 'in_use
', чтобы убедиться, что другие не хватают запись.
Поскольку MySQL не предлагает метод "NOWAIT", как Postgre или Oracle, я столкнулся с проблемами блокировки, когда рабочие потоки зависают и ждут, когда заблокированная строка станет доступной.
В попытке преодолеть это ограничение я попытался объединить всю необходимую обработку в одном операторе и запустить его с помощью метода execute()
ORM, хотя SQLAlchemy отказывается возвращать результат запроса.
Вот пример.
Мой оператор SQL:
SELECT id INTO @update_id FROM myTable WHERE in_use=0 ORDER BY id LIMIT 1 FOR UPDATE;
UPDATE myTable SET in_use=1 WHERE id=@update_id;
SELECT * FROM myTable WHERE id=@update_id;
И я запускаю этот код в консоли:
engine = create_engine('mysql://<user details>@<server details>/myDatabase', pool_recycle=90, echo=True)
result = engine.execute(sqlStatement)
result.fetchall()
Только чтобы получить этот результат
[]
Я уверен, что оператор выполняется, поскольку я вижу, как обновление вступает в силу в базе данных, и если я выполняю его через терминал mysql или другие инструменты, я получаю измененную строку, возвращаемую.
Кажется, это просто SQLAlchemy, который не хочет подтверждать возвращенную строку.
Есть ли что-то конкретное, что нужно сделать, чтобы ORM принял ответ?
Приветствия