Принуждение sqlalchemy ORM get () вне карты идентификации

Задний план

Метод get() является особым в ORM SQLAlchemy, потому что он пытается вернуть объекты из карты идентификации перед выпуском SQL-запроса в базу данных (см. Документацию ).

Это отлично подходит для производительности, но может вызвать проблемы для распределенных приложений, поскольку объект может быть изменен другим процессом, поэтому локальный процесс не знает, что объект грязный, и будет продолжать извлекать устаревший объект из карты идентификации, когда get() .


Вопрос

Как заставить force get() игнорировать карту идентификации и каждый раз вызывать вызов в БД?


пример

  • У меня есть объект Company определенный в ORM.
  • У меня есть price_updater() который обновляет атрибут stock_price всех объектов Company каждую секунду.
  • У меня есть buy_and_sell_stock() который иногда покупает и продает акции.
    • Теперь, внутри этого процесса, я, возможно, загрузил объект microsoft = Company.query.get(123) .
    • Через несколько минут я могу Company.query.get(123) еще один звонок для Company.query.get(123) . С тех пор цена акций изменилась, но мой buy_and_sell_stock() не знает об изменениях, потому что это произошло в другом процессе.
    • Таким образом, вызов get(123) возвращает устаревшую версию Company с карты идентификации сеанса, что является проблемой.

Я выполнил поиск по SO (под тегом [sqlalchemy]) и прочитал документы SQLAlchemy, чтобы попытаться выяснить, как это сделать, но не нашел пути.

One Solution collect form web for “Принуждение sqlalchemy ORM get () вне карты идентификации”

Использование session.expire(my_instance) приведет к повторному выбору данных при доступе. Однако, даже если вы используете expire (или expunge ), следующие данные, которые будут извлечены, будут основаны на уровне изоляции транзакции. См. Документы PostgreSQL по уровням изоляции (это относится и к другим базам данных), а также к документам SQLAlchemy об установке уровней изоляции .

Вы можете проверить, присутствует ли экземпляр в сеансе с: my_instance in session .

Вы можете использовать filter вместо того, чтобы обойти кеш , но он все равно имеет такое же ограничение уровня изоляции.

 Company.query.filter_by(id=123).one() 
  • SQLAlchemy & PassLib
  • Использование factory_boy с методами SQLAlchemy и класса
  • SQLAlchemy: выбор столбцов объекта в запросе
  • SqlAlchemy не будет принимать значение datetime.datetime.now в столбце DateTime
  • Использование DATEADD в sqlalchemy
  • Структура проекта для настольных приложений с использованием SQLAlchemy и wxPython
  • Обнаружение ссылок на объект SQLAlchemy
  • SQLalchemy AttributeError: объект 'str' не имеет атрибута '_sa_instance_state'
  • Python - лучший язык программирования в мире.