joined-table "macros" for select_from()

Issue #1459 resolved
Mike Bayer repo owner created an issue

this feature would begin to chip away at with_polymorphic() and is geared towards joined table loading. its not clear to what degree concrete could be involved.

mapper gains "defer_join":

mapper(Employee, employees, polymorphic_on=employees.c.type, defer_join=True)
mapper(Manager, managers, inherits=Employee, polymorphic_identity="manager")

meaning, a load for Manager would only query the Employee table. The additional attributes are loaded as needed. I don't think this is quite like 0.4's behavior which only spoke about when you query for Employee.

The load of all the columns is disabled/enabled via options, which can control any entity :

query(Manager).options(undefer_join(Manager))

query(Company).options(undefer_join(Manager)).join(Company.employees)

or maybe undefer_all(). undefer_all() would mix in to load all the deferred columns too, undefer_join() just the joined table minus whatever cols are deferred.

the above scenario illustrates the tricky part - if the options() were after the join(), the join() wouldn't take advantage of it - since join() constructs the SQL expression immediately and determines aliasing behavior for subsequent filter calls. I was going to recommend changing that too but that would be a much bigger subject to take on (it would be essentially a rewrite of Query).

of course when you join on a relation(), you can just use of_type() (right ?)

query(Company).join(Company.employees.of_type(Manager))

undefer_join() should be able to replace with_polymorphic() entirely, and can take similar arguments:

query(Employee).option(undefer_join(Manager), undefer_join(Engineer))

query(Employee).option(undefer_join([Manager,Engineer](Manager,Engineer), someselect, discriminator=someselect.c.foo))

the _MapperEntity will need to accept these options, and a decision needs to be made whether it should add the given undefer_join() entity to its existing _with_polymorphic collection or replace it - probably the list argument style would replace the list, or if the selectable is given.

Comments (5)

  1. Mike Bayer reporter

    weird. not liking the "defer"/"undefer" language here. I think for this we just need some shorthand for spelling out the tables, like:

    query(Employee, Vehicle).\
        select_from(
             polymorphic(Manager, Engineer).\
                 join(
                   polymorphic(Car, Train), 
                   Manager.vehicle_id==Vehicle.id
                 )
         )
    

    where above polymorphic(x, y, z) will produce an OUTER JOIN of the non-common tables of x, y and z against their common tables.

  2. Log in to comment