2012-04-02 4 views
1

По соображениям производительности наше приложение загружает определенные экземпляры модели SQLAlchemy в память во время запуска. Ожидается, что эти случаи не изменятся в течение срока действия приложения, поэтому это разумное решение.Объекты кэширования SQLAlchemy Помимо транзакции

По большей части это было нормально, но я наблюдал отдельные случаи, когда появляется DetachedInstanceError: Instance <ZZZ at 0x3a23510> is not bound to a Session; attribute refresh operation cannot proceed, что вызывает постоянные проблемы. Это та же ошибка, которую я ожидал бы (при ожидании) при попытке получить доступ к ленивым нагрузкам на аналогично кэшированном объекте.

Ошибка связана с доступом к атрибуту .id, который, как я полагал, не потребует какого-либо обновления базы данных для доступа. Меня действительно беспокоит то, что я не могу последовательно воспроизвести это исключение.

Мое вопрос заключается в том, что может вызвать это исключение и какие методы использовались для хранения экземпляров SQLAlchemy за пределами транзакции, которая их привела?

+0

Когда вы загружаете объект, он будет связан с сеансом, который извлекает его, если вы можете проверить 'obj in session', тогда он вернет вам« True ». Поэтому, когда вы пытаетесь получить доступ к '.id', убедитесь, что объект существует в этом сеансе или нет. – Nilesh

ответ

2

.id будет отсутствовать, если объект был истек, прежде чем он был помещен в кеш. После того, как сеанс завершает или откатывается, по умолчанию он истекает всеми атрибутами, которые обновляются при следующем доступе.

Это не то, что .id - это то, что он есть, поскольку объект, возможно, был удален из базы данных или изменен ее первичный ключ (оба условия будут испускать ObjectDeletedError).

Решение заключается в кэшировании объекта до истечения срока его действия, выключения() его из сеанса до истечения срока действия сеанса или отключения expire_on_commit.