support setting load options on instances

Issue #3037 new
Michael Bayer
repo owner created an issue

proof of concept

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(Integer, ForeignKey('a.id'))
    cs = relationship("C")

class C(Base):
    __tablename__ = 'c'

    id = Column(Integer, primary_key=True)
    b_id = Column(Integer, ForeignKey('b.id'))

e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)

sess = Session(e)
sess.add_all([
    A(bs=[
        B(cs=[C(), C()]),
        B(cs=[C(), C()])
    ])
])
sess.commit()

a1 = sess.query(A).first()
inspect(a1).load_options = inspect(a1).load_options.union([joinedload(B.cs)])

for b in a1.bs:
    print b.cs

im not sure why the above option doesn't have to mention "A.bs" at all, there should be some path logic taking this into account. The public API should be:

inspect(a1).set_load_option("bs", joinedload(...))

Comments (6)

  1. jvanasco

    what about when there are multiple items / depths to load and you want to consolidate into a single database action ?

    maybe something like...

    inspect(a1).set_load_option("bs", joinedload(...))
    inspect(a1).set_load_option("bs_cs", joinedload(...))
    inspect(a1).load_outstanding( ("bs", "bs_cs",) )
    
  2. Michael Bayer reporter
    • changed milestone to 1.3

    thoughts include:

    1. get rid of state.load_path and make the "path" local to the option as it is applied, inside of a wrapper WithPath() , so that we no longer have to worry about that

    2. MapperOption gets a method like "def apply_to_states(self, states)" which is the entrypoint

    3. deferred/lazy etc. loaders will need to learn how to apply their "callables" to the instance outside of a load, unless we want to modify the whole "callable" thing too

    4. session.apply_options(obj, options) session.apply_options_all(objects, options) ?

  3. Log in to comment