Как правильно отключить кеширование в сеансе ORM Sqlalchemy?

У меня есть поток в демонах, который выполняет цикл и выполняет следующий запрос:

try: newsletter = self.session.query(models.Newsletter).\ filter(models.Newsletter.status == 'PROCESSING').\ limit(1).one() except sa.orm.exc.NoResultFound: self.logger.debug('No PROCESSING newsletters found. Sleeping...') self.sleep() return # (...) more code to do with found newsletter 

Если метод sleep просто останавливает выполнение этого потока для настроенного времени, а оператор возврата возвращается в основной цикл. Однако я обнаружил, что если я изменю статус информационного бюллетеня на «ОБРАБОТКУ», пока демон работает, ничего не происходит, т.е. запрос все еще вызывает NoResultFound. Однако, если я перезапущу демона, он найдет информационный бюллетень. Поэтому я вижу, что результаты этого запроса должны быть кэшированы. Что я могу сделать, чтобы аннулировать кеш? session.expire_all () не работает. Я мог бы также создать новый объект Session () на каждой итерации, но не знаю, является ли это хорошим подходом к системным ресурсам.

4 Solutions collect form web for “Как правильно отключить кеширование в сеансе ORM Sqlalchemy?”

SQLAlchemy не кэширует сам по себе. Если вы явно не реализовали кеш, как этот .

Pass echo=True для вашего sessionmaker и посмотрите на вывод logging .

Проблема в вашем коде связана с базой данных с использованием уровня изоляции REPEATABLE READ по умолчанию, поэтому запрос возвращает тот же результат, если вы не вызываете commit() или rollback() (или не используете autocommit=True как предлагалось Xeross) или вручную изменяете уровень изоляции.

Да, SQLAlchemy кэширует сопоставленные объекты (а не результаты запроса!), Потому что для шаблона ORM требуется отдельный объект для каждого идентификатора. По умолчанию SQLAlchemy использует слабую идентификационную карту как кеш, поэтому объект автоматически удаляется из сеанса, когда нет ссылок на него. Обратите внимание, что последующие запросы будут обновлять состояние кэшированных объектов новыми данными, поэтому не нужно беспокоиться об этом кеше.

Хм, я уже нашел ответ, вам явно нужно явно выполнить session.commit (), чтобы его обновить, или вам нужно установить autocommit = True в сеансе, например, для sessionmaker.

 sessionmaker(bind=self.engine, autocommit=True) 

Однако я не проверял способ session.commit ()

Таким образом, это не проблема кэширования, это похоже на то, как работают транзакции

не использовать autocommit = True и expire_on_commit = True

 for state in self.identity_map.all_states(): state.expire(state.dict, self.identity_map._modified) 

вы можете: после запроса: db.session.commit ()

  • Странно, что мое соединение SQLAlchemy MySQL всегда заканчивается спать?
  • Почему я получаю «NameError» с этим импортом?
  • Как запросить для всех групп типа 'foo', которые содержат user_x? (таблица «многие-ко-многим»)
  • SQLAlchemy 2 внешних ключа к одному и тому же первому ключу
  • SQLAlchemy - модификация Mixin vs MetaClass
  • Как создать флеш-приложение вокруг уже существующей базы данных?
  • sqlalchemy и общий кэш SQLite
  • Связать объекты в отношениях «многие-ко-многим» в SQLAlchemy
  • Python - лучший язык программирования в мире.