Я только начал использовать SQLAlchemy и получить DetachedInstanceError и не могу найти много информации об этом в любом месте. Я использую экземпляр вне сеанса, поэтому естественно, что SQLAlchemy не может загружать какие-либо отношения, если они еще не загружены, однако атрибут, к которому я обращаюсь, не является отношением, на самом деле этот объект вообще не имеет отношения. Я нашел решения, такие как нетерпеливая загрузка, но я не могу применить к этому, потому что это не отношение. Я даже пытался "прикоснуться" к этому атрибуту до закрытия сеанса, но он все равно не предотвращает исключение. Что может вызвать это исключение для нереляционного свойства даже после того, как он был успешно достигнут один раз раньше? Любая помощь в отладке этой проблемы приветствуется. В то же время я попытаюсь получить воспроизводимый автономный сценарий и обновить его здесь.
Обновление: это фактическое сообщение с несколькими стеками:
File "/home/hari/bin/lib/python2.6/site-packages/SQLAlchemy-0.6.1-py2.6.egg/sqlalchemy/orm/attributes.py", line 159, in __get__
return self.impl.get(instance_state(instance), instance_dict(instance))
File "/home/hari/bin/lib/python2.6/site-packages/SQLAlchemy-0.6.1-py2.6.egg/sqlalchemy/orm/attributes.py", line 377, in get
value = callable_(passive=passive)
File "/home/hari/bin/lib/python2.6/site-packages/SQLAlchemy-0.6.1-py2.6.egg/sqlalchemy/orm/state.py", line 280, in __call__
self.manager.deferred_scalar_loader(self, toload)
File "/home/hari/bin/lib/python2.6/site-packages/SQLAlchemy-0.6.1-py2.6.egg/sqlalchemy/orm/mapper.py", line 2323, in _load_scalar_attributes
(state_str(state)))
DetachedInstanceError: Instance <ReportingJob at 0xa41cd8c> is not bound to a Session; attribute refresh operation cannot proceed
Частичная модель выглядит следующим образом:
metadata = MetaData()
ModelBase = declarative_base(metadata=metadata)
class ReportingJob(ModelBase):
__tablename__ = 'reporting_job'
job_id = Column(BigInteger, Sequence('job_id_sequence'), primary_key=True)
client_id = Column(BigInteger, nullable=True)
И поле client_id - это то, что вызывает это исключение, с использованием, как показано ниже:
Query:
jobs = session \
.query(ReportingJob) \
.filter(ReportingJob.job_id == job_id) \
.all()
if jobs:
# FIXME(Hari): Workaround for the attribute getting lazy-loaded.
jobs[0].client_id
return jobs[0]
Это то, что затем вызывает исключение из области сеанса:
msg = msg + ", client_id: %s" % job.client_id