I do want it to tell me when stuff is being eager loaded so I can optimize
those queries.
SQLAlchemy shouldn't need to know about the other end of the relationship
to delete the person should it?
I didn't notice this before, but when I add passive_deletes=True on the
"many" side I get the warning:
SAWarning: On Person.category, 'passive_deletes' is normally configured on
one-to-many, one-to-one, many-to-many relationships only.
If I move the passive_deletes to the "one" side I get the exception again.
On Friday, August 3, 2018 at 2:29:45 PM UTC-5, Derek Lambert wrote:
>
> 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.