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.

Reply via email to