Hello Michael,
Thank you for your reply and for SA!
> you could also try the "relations" relation mapping using just a
> single "primaryjoin" across the two tables. *or*, not even have it
> and just use a property accessor, this is the cleaner way to do it:
>
> def _relations(self):
> foreach x in self.relation_direct:
> foreach y in x.relation_inverse:
> yield y
> def _add_relation(self, info):
> info.relation_inverse.append(self)
> self.relation_direct.append(info)
> relations = property(_relations, _add_relation)
The yield and property() were new to me but after reading about them I
don't understand your example. If I understand correctly these are
Information methods. Both relation_inverse and relation_direct are lists
of Relationship objects so I believe I cannot append an Information object
to them.
I adapted your code while adding backreferences to the information mapper:
properties = { 'relation_direct' : relation(Relationship,
primaryjoin=(info_table.c.pk == rel_table.c.info_fk_one),
backref='info_direct'),
'relation_inverse' : relation(Relationship,
primaryjoin=(info_table.c.pk == rel_table.c.info_fk_two),
backref='info_inverse')}
Information.mapper = mapper(Information, info_table,
properties = properties)
Relationship.mapper = mapper(Relationship, rel_table)
class Information(object):
def __init__(self, info):
self.info = info
def _relations(self):
for x in self.relation_direct:
yield x.info_inverse
def _add_relation(self, info):
self.relation_direct.append(Relationship(self, info[0], info[1]))
relations = property(_relations, _add_relation)
With this I can add a relation with:
i1.relations = (i4, "Father")
and get all of John's relations with:
iq1=session.query(Information).get_by(info="John")
for n in iq1.relations:
print iq1.info + " is related to " + n.info
The problem with this approach is that a SELECT is issued to the database
in every iteration of the for loop. Any suggestions to overcome this?
>> My second question is if it is possible to do a query on
>> Information based
>> on rel_data (attribute of Relationship), like a query that returns
>> all of
>> John's nephews (rel_data = "Uncle")?
>>
>> I think the SQL output of the ORM should be something like:
>>
>> SELECT infos2.pk, infos2.info FROM infos
>> JOIN rels ON infos.pk = rels.info_fk_one
>> JOIN infos AS infos2 ON rels.info_fk_two = infos2.pk
>> WHERE infos.pk = ? AND rels.rel_data = ?
>>
>
> info2 = info_table.alias('info2')
> session.query(Information).select(
> info_table.select(
> and_(info2.c.pk==17,rel_table.c.rel_data=='somedata'),
> from_obj=[info_table.join(rel_table,
> info_table.c.pk==rel_table.c.info_fk_one).join(info2,
> info2.c.pk==rel_table.c.info_fk_two)]
> )
> )
This selects on info_table but I need to select on info2. I didn't manage
to select on info2 but I turned the select around and did it like this:
info2 = info_table.alias('info2')
session.query(Information).select(
info_table.select(
and_(info2.c.pk==iq1.pk,rel_table.c.rel_data=='Uncle'),
from_obj=[info_table.join(rel_table,
info_table.c.pk==rel_table.c.info_fk_two).join(info2,
info2.c.pk==rel_table.c.info_fk_one)]
)
)
Thanks again for your help!
--
Rúben Leote Mendes -- [EMAIL PROTECTED]
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Sqlalchemy-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users