I mean really, it might not be that hard to just get ForeignKey to accept a callable, it just would have to be explicitly supported. the mechanics got much more complicated when i got the whole “we use the type from the parent column” thing to work 100%.
On Jan 13, 2014, at 3:46 PM, Michael Bayer <[email protected]> wrote: > because the event is the public, stable API ;). I’d prefer the > _set_parent() is a no-op but at the moment there’s a NotImplementedError in > there. > > > On Jan 13, 2014, at 3:22 PM, Alessandro Molina <[email protected]> > wrote: > >> Looks good, just one curiosity, is there a reason for using >> "after_parent_attach" event instead of directly using _set_parent to >> register the LazyForeignKey for being resolved? >> >> >> 2014/1/13 Michael Bayer <[email protected]> >> >> On Jan 13, 2014, at 1:19 PM, Alessandro Molina <[email protected]> >> wrote: >> >>> Just noticed that SQLAlchemy 0.9 broke a LazyForeignKey class that was >>> provided by TurboGears tgext.pluggable to make possible to declare foreign >>> keys to models not yet defined at the time the ForeignKey was declared. >>> >>> The main use was something like: >>> >>> class User(DeclarativeBase): >>> __tablename__ = 'users' >>> >>> registration_id = Column(Integer, LazyForeignKey(lambda: >>> app_model.Registration.uid)) >>> >>> where app_model.Registration was available only at runtime and not when >>> User class was declared. >>> Also app_model.Registration table name was not known (as it dynamically >>> generated to avoid collision between tables of multiple apps plugged at >>> runtime), so it was not possible to declare the foreign key as a string >>> with the "tablename.column_name" syntax. >>> >>> LazyForeignKey was simply implemented as a subclass of ForeignKey which >>> provided a custom _colspec property which would resolve the given function >>> whenever it was first accessed: >>> https://github.com/TurboGears/tgext.pluggable/blob/master/tgext/pluggable/sqla/relations.py#L4 >>> >>> This approach doesn't work anymore in SQLA 0.9 as _colspec gets accessed by >>> the ForeignKey constructor itself, calling the lambda at Column declaration >>> time. >>> >>> It seems to me that adapting the LazyForeignKey class to SQLA 0.9 would >>> require messing a lot more with SQLAlchemy internal code, which is >>> something I would like to avoid. >>> >>> What would be the suggested way to achieve the same feature on SQLA 0.9? >> >> Well if the table name were known, then you wouldn’t need such a feature in >> the first place as you can just put a string name in ForeignKey(). >> >> However, as this seems to be a case where a table + declared class is to >> eventually refer to some other Table whose name is not known yet, the >> ForeignKey() should not exist on the Column at all until that other Table is >> available. A simple call to >> User.__table__.append_constraint(ForeignKeyConstraint(<now you know what to >> put here>)) at the time this information is known would be the cleanest. >> >> to get at this you’d need to use events. First a way to make an XYZ() >> object that can be placed inside of Column and know about it: >> >> >> from sqlalchemy.schema import SchemaItem >> from sqlalchemy import event >> >> class MyThing(SchemaItem): >> def _set_parent(self, parent): >> pass >> >> @event.listens_for(MyThing, "after_parent_attach") >> def my_thing_attached(target, parent): >> print("Attaching target %s to parent %s", target, parent) >> >> from sqlalchemy import Table, MetaData, Column, Integer >> >> Table('t', MetaData(), Column('x', Integer, MyThing())) >> >> Then you want to register your LazyForeignKey object in a registry that will >> allow the callable to be invoked once your “table setup” system has >> completed - you’d call the callable, construct a ForeignKeyConstraint, then >> append it to the constraints of the parent column.table. >> >> the only private API in use here is the _set_parent() override. If I >> change that API it would be something simple. >> >> >> -- >> 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 [email protected]. >> To post to this group, send email to [email protected]. >> Visit this group at http://groups.google.com/group/sqlalchemy. >> For more options, visit https://groups.google.com/groups/opt_out. >
signature.asc
Description: Message signed with OpenPGP using GPGMail
