Christoph Zwerschke wrote:
> But that expression needs to be parsed to SQL anyway, and doing so all > involved columns could be tracked. Another clue is that the class for > the relation object has been stated as 'Group' which is mapped to > pg_group. Why do you actually need a Foreign*Key*, not a Foreign*Table*? yes, i could absolutely parse it out. you should dig around the source code a little bit to see how that works, including the diffs for the revsion i just made for this one which illustrate how its done. with regards to "foreignkey", i am just not totally comfortable throwing some more "automatic" behavior in there just yet, for reasons already stated, since its easy enough to state it explicitly. the "foreignkey" parameter is still undergoing an evolution and a clarification, which is one reason its still a little murky as to what its used for and what it needs to know. it accomplishes multiple things and i have not yet worked out a really good way to clarify its individual roles. currently, heres why its a list of columns: - for a self-referential mapper or other self-referring table relationship, where theres only one table anyway...we need to know specific columns in that case in order to determine what kind of relationship we are looking at. - it can account for all the foreign key columns in a more complicated join condition, where maybe only one of those columns actually points to the target table and therefore has meaning. - it is used in the determination of the "lazy clause" in a self-referential table relationship so that it can determine what columns in the clause get converted into a bind parameter for a lazy load. - i have recently stepped up its role to also indicate which column-mapped attributes should actually be "synchronized" when objects are connected together or detached during flush time. here is a snippet of the recent example someone had (which is also present in the "relationships.py" unit test if you want to play with it): pageversions = Table("pageversions", metadata, Column("jobno", Unicode(15), primary_key=True), Column("pagename", Unicode(30), primary_key=True), Column("version", Integer, primary_key=True, default=1), ) ) pages = Table("pages", metadata, Column("jobno", Unicode(15), ForeignKey("jobs.jobno"), primary_key=True), Column("pagename", Unicode(30), primary_key=True), Column("current_version", Integer)) mapper(Page, pages, properties={ 'currentversion': relation(PageVersion, foreignkey=pages.c.current_version, primaryjoin=and_(pages.c.jobno==pageversions.c.jobno, pages.c.pagename==pageversions.c.pagename, pages.c.current_version==pageversions.c.version), post_update=True), 'versions': relation(PageVersion, cascade="all, delete-orphan", primaryjoin=and_(pages.c.jobno==pageversions.c.jobno, pages.c.pagename==pageversions.c.pagename), order_by=pageversions.c.version, backref=backref('page', lazy=False, primaryjoin=and_(pages.c.jobno==pageversions.c.jobno, pages.c.pagename==pageversions.c.pagename))) }) above, the "Page" object points to a list of PageVersion objects, via the "versions" relation. however, there is also a second relationship between them called "currentversion", which refers to the "current" entry in the "versions" relation. When a given PageVersion becomes the "currentversion", the "current_version" column in Page gets set to its "version" value, and when it is removed as the "currentversion", the "version" value gets removed. However, the other columns in the join condition (jobno and pagename) do not change. In this example they are primary key columns, and nulling them out raises an error on flush. the "foreignkey" here refers only to "current_version" and indicates the only column that actually needs to be changed when attaching/detaching the "currentversion" to "Page". its pretty impressive to me how far SA has managed to go with its current relationship-definition model, which is literally a SQL expression and a list of columns...because it is so sparse yet it is more powerful than any other system I have ever seen (including hibernate by a mile). it might be time for a less sparse approach to the whole thing, for reasons of clarity, but it hasnt really dawned on me yet what that might look like. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy -~----------~----~----~----~------~----~------~--~---