Hi, I observed some strange (for me) behavior related to setting query options. I am not sure if it works as intended or it is a bug. It seems to me that options are applied to query in a strange manner. The posted below the code that show this behavior: 1) in both tests I am configuring sqlalchemy to raise an exception when A.bs relation is accessed 2) but in test number 1, I am not assigning result of running query (i.e. I am not reading it as I understand, since it is lazy) and exception is not raised. 3) on the other hand in test number 2, I am assigning this result to variable 'x' and an exception is raised (this is the only difference between tests). 4) It does not matter if I run test_1 prior to test_2. 5) I tested it on current (1.2.12) version of sqlalchemy.
Documentation (https://docs.sqlalchemy.org/en/latest/orm/loading_relationships.html#controlling-loading-via-options) suggests that setting this option should be possible in the way I am doing it in test 1, but I think that my case shows that it does not. Does it work as it is supposed to work and I am missing something or is it a bug? Creating and populating tables: from sqlalchemy import Column, Integer, String, orm, ForeignKey, create_engine from sqlalchemy.orm import relationship, Session from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class A(Base): __tablename__ = 'a' id = Column(Integer, primary_key=True) name = Column(String) def __repr__(self): return '<A id: {}, name: {}>'.format(self.id, self.name) class B(Base): __tablename__ = 'b' id = Column(Integer, primary_key=True) a_id = Column(Integer, ForeignKey('a.id'), index=True) a = relationship('A', backref='bs') def __repr__(self): return '<B id: {}, a_id: {}>'.format(self.id, self.a_id) e = create_engine("sqlite://", echo=True) Base.metadata.create_all(e) s = Session(e) s.add(A(id=1, name='A1', bs=[B()])) s.add(A(id=2, name='A2', bs=[B(), B()])) s.commit() Tests definition: def test_1(): # This DOES NOT affect further queries print('------------------------ Test 1 ------------------------') s.query(A).options(orm.raiseload(A.bs)).filter_by(id=1).all() print(s.query(A).filter_by(id=1).all()[0].bs) def test_2(): # This DOES affect further queries print('------------------------ Test 2 ------------------------') x = s.query(A).options(orm.raiseload(A.bs)).filter_by(id=1).all() print(s.query(A).filter_by(id=1).all()[0].bs) test_1() test_2() test_1 does not raise any exception, while test_2 raises: --------------------------------------------------------------------------- InvalidRequestError Traceback (most recent call last) <ipython-input-2-6aad37f5c088> in <module> 24 create_data() 25 test_1() ---> 26 test_2() <ipython-input-2-6aad37f5c088> in test_2() 19 print('------------------------ Test 2 ------------------------') 20 x = s.query(A).options(orm.raiseload(A.bs)).filter_by(id=1).all() ---> 21 print(s.query(A).filter_by(id=1).all()[0].bs) 22 23 ~/Envs/importer/lib/python3.6/site-packages/sqlalchemy/orm/attributes.py in __get__(self, instance, owner) 240 return dict_[self.key] 241 else: --> 242 return self.impl.get(instance_state(instance), dict_) 243 244 ~/Envs/importer/lib/python3.6/site-packages/sqlalchemy/orm/attributes.py in get(self, state, dict_, passive) 597 elif key in state.callables: 598 callable_ = state.callables[key] --> 599 value = callable_(state, passive) 600 elif self.callable_: 601 value = self.callable_(state, passive) ~/Envs/importer/lib/python3.6/site-packages/sqlalchemy/orm/strategies.py in __call__(self, state, passive) 832 strategy = prop._strategies[self.strategy_key] 833 --> 834 return strategy._load_for_state(state, passive) 835 836 ~/Envs/importer/lib/python3.6/site-packages/sqlalchemy/orm/strategies.py in _load_for_state(self, state, passive) 587 588 if self._raise_always: --> 589 self._invoke_raise_load(state, passive, "raise") 590 591 session = _state_session(state) ~/Envs/importer/lib/python3.6/site-packages/sqlalchemy/orm/strategies.py in _invoke_raise_load(self, state, passive, lazy) 562 def _invoke_raise_load(self, state, passive, lazy): 563 raise sa_exc.InvalidRequestError( --> 564 "'%s' is not available due to lazy='%s'" % (self, lazy) 565 ) 566 InvalidRequestError: 'A.bs' 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.
