[Sqlalchemy-tickets] [sqlalchemy] #2750: Inconsistent behavior for polymorphic queries
Brought to you by:
zzzeek
|
From: sqlalchemy <mi...@zz...> - 2013-06-07 15:21:57
|
#2750: Inconsistent behavior for polymorphic queries
----------------------+-----------------------------------------
Reporter: schlamar | Owner: zzzeek
Type: defect | Status: new
Priority: medium | Milestone:
Component: orm | Severity: no triage selected yet
Keywords: | Progress State: awaiting triage
----------------------+-----------------------------------------
This is my test case:
{{{
#!python
from sqlalchemy import create_engine, Column, ForeignKey, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Model(Base):
__tablename__ = 'model'
id = Column(Integer, primary_key=True)
label = Column(String)
mtype = Column(Integer, nullable=False)
__mapper_args__ = {'polymorphic_on': mtype}
class SubModel(Model):
__tablename__ = 'submodel'
id = Column(Integer, ForeignKey('model.id'), primary_key=True)
__mapper_args__ = {'polymorphic_identity': 1}
def main():
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
m = Model(mtype=1)
m.label = 'x'
session.add(m)
session.commit()
m_id = m.id
session = Session()
m = session.query(Model).get(m_id)
m.label = 'y'
session.commit()
print m.id
}}}
This yields the following error:
{{{
Traceback (most recent call last):
File "sqla_test.py", line 44, in <module>
main()
File "sqla_test.py", line 40, in main
print m.id
File "D:\Projekte\HACS\packages\sqlalchemy\orm\attributes.py", line 316,
in __get__
return self.impl.get(instance_state(instance), dict_)
File "D:\Projekte\HACS\packages\sqlalchemy\orm\attributes.py", line 611,
in get
value = callable_(passive)
File "D:\Projekte\HACS\packages\sqlalchemy\orm\state.py", line 375, in
__call__
self.manager.deferred_scalar_loader(self, toload)
File "D:\Projekte\HACS\packages\sqlalchemy\orm\loading.py", line 606, in
load_scalar_attributes
raise orm_exc.ObjectDeletedError(state)
sqlalchemy.orm.exc.ObjectDeletedError: Instance '<SubModel at 0x2f0eeb0>'
has been deleted, or its row is otherwise not
present.
}}}
I have already investigated and can explain the behavior: the query
returns actually a !SubModel instance because of `mtype == 1`. After the
commit the object is expired so a new query is issued which joins model
against submodel. But an entry in the submodel table was never created.
This behavior is really inconsistent. SQLAlchemy should throw an error on
the query or on the insert. Alternatively, it might fix the insert
automatically by creating an corresponding entry to submodel.
Besides, if you issue `session.query(SubModel).get(m_id)` you get the same
error message, which is really misleading.
--
Ticket URL: <http://www.sqlalchemy.org/trac/ticket/2750>
sqlalchemy <http://www.sqlalchemy.org/>
The Database Toolkit for Python
|