On Tuesday, June 28, 2016 at 2:57:08 PM UTC+1, Mike Bayer wrote: > > > > On 06/28/2016 05:28 AM, mic...@healx3.com <javascript:> wrote: > > Hello! I sometimes find it more convenient to create to construct a > > query without a session, and then to add the session at the end using > > `with_session`. In particular, when constructing non-trivial queries, > > not having to pass the session around means one less argument to manage. > > However, this doesn't seem to work when using subquery loading, > > resulting in the error `AssertionError: Subquery session doesn't refer > > to that of our context. Are there broken context caching schemes being > > used?`. > > > > Is there a sensible way to get the subqueries to use the same session, > > or is the answer just to always construct queries with the session? > > > that assertion only applies to when the internal QueryContext is being > re-used, as is the case with baked query loading. The QueryContext > itself created during the _compile_context() phase will contain > references to the Session within the subquery eager loaders. As long > as you don't do anything with your original query other than call > with_session(), there's no error I can reproduce, e.g.: > > from sqlalchemy import * > from sqlalchemy.orm import * > from sqlalchemy.ext.declarative import declarative_base > > Base = declarative_base() > > > class A(Base): > __tablename__ = 'a' > id = Column(Integer, primary_key=True) > bs = relationship("B") > > class B(Base): > __tablename__ = 'b' > id = Column(Integer, primary_key=True) > a_id = Column(ForeignKey('a.id')) > > e = create_engine("sqlite://", echo=True) > Base.metadata.create_all(e) > > s = Session(e) > s.add_all([A(bs=[B(), B()]), A(bs=[B(), B()])]) > s.commit() > > q1 = Session().query(A).options(subqueryload(A.bs)) > > for sess in [Session(e), Session(e), Session(e)]: > for a in q1.with_session(sess): > print a, a.bs > > > > Please work up an example showing how you're getting that result, thanks! > > Thanks for the quick reply, and apologies for not providing an example in the first place. I think I worked out the issue: we've wrapped up the session:
class TransactionalSession(object): def __init__(self, session): self._session = session def __enter__(self): return self def __exit__(self, exception_type, exception, traceback): if exception is None: self._session.commit() else: self._session.rollback() self._session.close() def __getattr__(self, key): return getattr(self._session, key) so when we try running the queries with subquery loading (for instance, as in your example, but with `TransactionalSession(Session(e))`), the session on `subq` is the underlying session, while the session on `context` is our own wrapped session. So, presumably the saner way of doing this would be either to use the underlying session directly, or to subclass `Session`? > > > > > > Thanks > > > > Michael > > > > -- > > 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+...@googlegroups.com <javascript:> > > <mailto:sqlalchemy+unsubscr...@googlegroups.com <javascript:>>. > > To post to this group, send email to sqlal...@googlegroups.com > <javascript:> > > <mailto:sqlal...@googlegroups.com <javascript:>>. > > Visit this group at https://groups.google.com/group/sqlalchemy. > > For more options, visit https://groups.google.com/d/optout. > -- 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.