On Mon, Aug 6, 2018 at 4:14 PM, Derek Lambert <dlamb...@dereklambert.com> wrote:
> 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.

the lazy load here doesn't need to actually fire off so just limit
your raiseload to sql only:

orm.raiseload('*', sql_only=True)

test script passes




>
> 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 sqlalchemy+unsubscr...@googlegroups.com.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.

-- 
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 sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to