If it were me I'd still try to solve the problem of deciding which relationships/backrefs need the setting up front. You can limit it to those who are setting up lazy="joined" I assume, and i'd consider getting ugly too with some hardcoding, since this is for legacy support anyway.
Otherwise the internal API magic you need would be:
from sqlalchemy.orm.interfaces import StrategizedProperty
prop.strategy_class = strategies.factory('subquery')
StrategizedProperty.do_init(prop)
which would reset the "self.strategy" attribute and the collection of alternate strategies.
> Thank you!
>
> I don't disagree: I've been brainstorming how to work it out upfront,
> but I think I'd need your topological sort to put the mappers in the
> correct dependency order and since it is legacy support, I'm ok with
> the non public API and potential consequences.
>
> I had tried prop.do_init() in place of
> StrategizedProperty.do_init(prop), but it failed.
>
> Why??? (would invoke RelationshipProperty.do_init(), but I would have
> guess that was the correct method instead of StrategizedProperty's)
here it is:
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Parent(Base):
__tablename__ = 'parent'
id = Column(Integer, primary_key=True)
children = relationship("Child", lazy='joined', backref=backref('parent', lazy='joined'))
class Child(Base):
__tablename__ = 'child'
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey('parent.id'))
compile_mappers()
from sqlalchemy.orm import strategies, interfaces
for prop in (Parent.children.property, Child.parent.property):
prop.strategy_class = strategies.factory('subquery')
interfaces.StrategizedProperty.do_init(prop)
e = create_engine('sqlite://', echo=True)
Base.metadata.create_all(e)
s = Session(e)
s.add(Parent(children=[Child(), Child()]))
s.commit()
print "----------------------"
s.query(Parent).all()
s.close()
print "----------------------"
s.query(Child).all()
> --
> You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
> To post to this group, send email to sqlal...@googlegroups.com.
> To unsubscribe from this group, send email to sqlalchemy+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
>
> Yep, works excellent (the "Why??" I asking about why is it wrong to
> invoke "prop.do_init()" instead of StrategizedProperty.do_init(prop))
oh. because you don't want to rerun all the initialization crap in RelationshipProperty which I'm not even sure supports being run on itself twice. So just StrategizedProperty's part is run.
this of course could be a public API function, but then it falls into the why-is-1%-of-SQLA-configuration-mutable-and-not-the-other-99% issue we had like when you were mutating table.c that time.