hello sqlalchemy,

i'm setting up a data structure that builds a group of trees using
combined primary keys. i got it to work (with help from rmancy on irc),
but it is far from intuitive.

my code looks like this:

ql =  Table('ql', metadata,
            # that's not the original column sort order, but it shouldn't matter
            Column(u'qid', Integer, primary_key=True),
            Column(u'lang', String(5), primary_key=True),
            Column(u'version', Integer, primary_key=True),
            Column(u'reflang', String(5), ForeignKey('ql.lang')),
            Column(u'refversion', Integer, ForeignKey('ql.version')),
            Column(...),
    )


class QL(object):
    def __repr__(self):
        return '<QL (%s, %s, %s)>'%(self.qid, self.lang, self.version)


mapper(QL, ql, properties={
        ...,
        'ref': relationship(
            QL,
            primaryjoin=and_(
                ql.c.qid==ql.c.qid,
                ql.c.reflang==ql.c.lang,
                ql.c.refversion==ql.c.version),
            backref=backref('backref'),
            foreign_keys=[ql.c.qid, ql.c.reflang, ql.c.refversion],
            remote_side=[ql.c.qid, ql.c.lang, ql.c.version]),
    })

my problem is that the primaryjoin query is rather unintellegible --
which side is which? i tried to substitude the right sides of the
primaryjoin and the remote_side items with referenced_ql =
ql.alias('referenced_ql'), but that made the query construction fail
with "Could not locate any equated, locally mapped column pairs for
primaryjoin condition ...". 

is there any way to express this more clearly?

(what came to my mind immediately was an expression like

..., primaryjoin=lambda local, remote: and_(local.c.qid==remote.c.qid,
local.c.reflang==remote.c.lang, local.c.refversion==remote.c.version),
...

where the mapper itself creates properly aliased versions of the
relevant tables, and later knows which is which, and passes them to a
function that defines the WHERE clause. i looked around in the code a
bit and found that something goes on with re-aliasing the query (not
sure about that) with primary_aliasizer; having an option to do this
more explicitly would seem more pythonic to me.)


regards
chrysn

-- 
To use raw power is to make yourself infinitely vulnerable to greater powers.
  -- Bene Gesserit axiom

Attachment: signature.asc
Description: Digital signature

Reply via email to