relationship loading strategy `expired`

Issue #3017 resolved
Ronny Pfannschmidt created an issue

currently all relationship loading loads the object on access

to use such objects without hitting the database, i propose a loading strategy which returns an expired instance with only the identity key set

roguhly the equivalent of

def hull(session, class_, *pk):
  mapper = class_mapper(class_)
  obj = class_()
  inspect(obj).key = mapper.identity_key_from_primary_key(pk)
  session.add(obj)
  session.expire(obj)
  return obj

Comments (6)

  1. Mike Bayer repo owner

    the best I can do here is add a unit test that exercises this specific process to ensure it remains working as expected (setting "key"), and maybe make some of the internal API more public, some function that will generate the new instance for you rather than you calling upon the "init()" method, as you'd like this instance to look like it was loaded from the DB.

    As far as "loader strategy" that doesn't make any sense as you're looking here to not load anything. a loader strategy takes effect when you call query().

  2. Ronny Pfannschmidt reporter

    loader strategy as in configuring a relationship to return hulls intead of instances

    i.e.

    class Foo(Base):
      id = Column(...)
      bar_id = Column(...)
      bar = relationship(Bar, lazy='hollow')
    
  3. Mike Bayer repo owner
    • Added new utility function :func:.make_transient_to_detached which can be used to manufacture objects that behave as though they were loaded from a session, then detached. Attributes that aren't present are marked as expired, and the object can be added to a Session where it will act like a persistent one. fix #3017

    → <<cset 9f74861d6d29>>

  4. Mike Bayer repo owner

    that doesn't make any sense. If you say "foo.bar", that means, "emit SQL". that's not the use case you showed me. the use you showed me is, you want to manufacture a "Bar" object and just attach it there.

  5. Mike Bayer repo owner

    oh you mean you want it to look at foo.bar_id and puff up the object? that's not really appropriate. The ORM has a very simple relationship with the database - it only knows about the rows that it loads. Any trickery like manufacturing fake rows is outside of that. this is not a strategy I'd ever want anyone to come across as it's an unsafe practice and will totally confuse people.

  6. Mike Bayer repo owner

    the strategy system is extensible though so feel free to inject make_transient_to_detached into a custom strategy.

  7. Log in to comment