When deleting a child object in a one-to-many relationship retrieved with
the raiseload('*') query option an exception is raised. Adding
passive_deletes=True to the relationship on the child prevents the
exception, but that seems like a hack.
I can remove the option from the query, but I'm trying to understand the
behavior here. Is this expected?
import sqlalchemy as sa
import sqlalchemy.orm as orm
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Person(Base):
id = sa.Column(sa.Integer, autoincrement=True,
primary_key=True)
category_id = sa.Column(sa.Integer, sa.ForeignKey('category.id'),
nullable=False)
name = sa.Column(sa.String)
category = orm.relationship('Category', back_populates='persons',
innerjoin=True)
__tablename__ = 'person'
class Category(Base):
id = sa.Column(sa.Integer, autoincrement=True, primary_key=True)
name = sa.Column(sa.String, unique=True)
persons = orm.relationship('Person', back_populates='category')
__tablename__ = 'category'
engine_url = 'postgresql+psycopg2://postgres@localhost/test_test'
engine = sa.create_engine(engine_url, echo=True)
engine.execute('DROP TABLE IF EXISTS "person"')
engine.execute('DROP TABLE IF EXISTS "category"')
Base.metadata.create_all(engine)
session = orm.sessionmaker(bind=engine)()
category1 = Category(name='Category1')
session.add(category1)
session.commit()
session.flush()
person = Person(category=category1, name='Some guy')
session.add(person)
session.commit()
session.flush()
session.expunge_all()
person = session.query(Person).filter(Person.name == 'Some
guy').options(orm.raiseload('*')).one()
session.delete(person)
session.commit()
This raises:
Traceback (most recent call last):
File "/Users/dereklambert/Development/test/misc/test_raise_load.py", line
52, in <module>
session.commit()
File
"/Users/dereklambert/Development/test/venv/lib/python3.6/site-packages/sqlalchemy/orm/session.py",
line 943, in commit
self.transaction.commit()
File
"/Users/dereklambert/Development/test/venv/lib/python3.6/site-packages/sqlalchemy/orm/session.py",
line 467, in commit
self._prepare_impl()
File
"/Users/dereklambert/Development/test/venv/lib/python3.6/site-packages/sqlalchemy/orm/session.py",
line 447, in _prepare_impl
self.session.flush()
File
"/Users/dereklambert/Development/test/venv/lib/python3.6/site-packages/sqlalchemy/orm/session.py",
line 2254, in flush
self._flush(objects)
File
"/Users/dereklambert/Development/test/venv/lib/python3.6/site-packages/sqlalchemy/orm/session.py",
line 2380, in _flush
transaction.rollback(_capture_exception=True)
File
"/Users/dereklambert/Development/test/venv/lib/python3.6/site-packages/sqlalchemy/util/langhelpers.py",
line 66, in __exit__
compat.reraise(exc_type, exc_value, exc_tb)
File
"/Users/dereklambert/Development/test/venv/lib/python3.6/site-packages/sqlalchemy/util/compat.py",
line 249, in reraise
raise value
File
"/Users/dereklambert/Development/test/venv/lib/python3.6/site-packages/sqlalchemy/orm/session.py",
line 2344, in _flush
flush_context.execute()
File
"/Users/dereklambert/Development/test/venv/lib/python3.6/site-packages/sqlalchemy/orm/unitofwork.py",
line 370, in execute
postsort_actions = self._generate_actions()
File
"/Users/dereklambert/Development/test/venv/lib/python3.6/site-packages/sqlalchemy/orm/unitofwork.py",
line 329, in _generate_actions
if action.execute(self):
File
"/Users/dereklambert/Development/test/venv/lib/python3.6/site-packages/sqlalchemy/orm/unitofwork.py",
line 463, in execute
prop_has_changes(uow, delete_states, True) or
File
"/Users/dereklambert/Development/test/venv/lib/python3.6/site-packages/sqlalchemy/orm/dependency.py",
line 234, in prop_has_changes
passive)
File
"/Users/dereklambert/Development/test/venv/lib/python3.6/site-packages/sqlalchemy/orm/unitofwork.py",
line 225, in get_attribute_history
attributes.LOAD_AGAINST_COMMITTED)
File
"/Users/dereklambert/Development/test/venv/lib/python3.6/site-packages/sqlalchemy/orm/attributes.py",
line 753, in get_history
current = self.get(state, dict_, passive=passive)
File
"/Users/dereklambert/Development/test/venv/lib/python3.6/site-packages/sqlalchemy/orm/attributes.py",
line 597, in get
value = callable_(state, passive)
File
"/Users/dereklambert/Development/test/venv/lib/python3.6/site-packages/sqlalchemy/orm/strategies.py",
line 834, in __call__
return strategy._load_for_state(state, passive)
File
"/Users/dereklambert/Development/test/venv/lib/python3.6/site-packages/sqlalchemy/orm/strategies.py",
line 589, in _load_for_state
self._invoke_raise_load(state, passive, "raise")
File
"/Users/dereklambert/Development/test/venv/lib/python3.6/site-packages/sqlalchemy/orm/strategies.py",
line 564, in _invoke_raise_load
"'%s' is not available due to lazy='%s'" % (self, lazy)
sqlalchemy.exc.InvalidRequestError: 'Person.category' is not available due
to lazy='raise'
--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
http://www.sqlalchemy.org/
To post example code, please provide an MCVE: Minimal, Complete, and Verifiable
Example. See http://stackoverflow.com/help/mcve for a full description.
---
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.