right this is why reading the docs is better, those have been checked… remote side for m2o refers to the primary key, so:
from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class Animal(Base): __tablename__ = 'animals' id_ = Column(Integer, primary_key=True) sire_id = Column(Integer, ForeignKey('animals.id_')) dam_id = Column(Integer, ForeignKey('animals.id_')) sire = relationship('Animal', foreign_keys=[sire_id], remote_side=id_) dam = relationship('Animal', foreign_keys=[dam_id], remote_side=id_) pjoin = 'and_(Animal.sire_id == Animal.id_, Animal.dam_id == Animal.id_)' children = relationship('Animal', primaryjoin=pjoin) e = create_engine("sqlite://", echo=True) Base.metadata.create_all(e) s = Session(e) a1, a2, a3, a4 = Animal(), Animal(), Animal(), Animal() a1.sire = a3 a1.dam = a4 a2.sire = a3 a2.dam = a3 s.add_all([a1, a2, a3, a4]) s.commit() assert a3.children == [a2] also reading the terms here, what’s “children” supposed to be? wouldn’t that “AND” be an “OR” here if I understand correctly? On Feb 14, 2014, at 2:40 PM, Michael Hipp <mich...@redmule.com> wrote: > On 2/14/2014 11:50 AM, Michael Bayer wrote: >> On Feb 14, 2014, at 12:46 PM, Michael Hipp <mich...@redmule.com> wrote: >> >>> On 2/13/2014 11:45 AM, Michael Bayer wrote: >>>> So for "children" above you need to spell out primaryjoin completely which >>>> is primaryjoin="and_(Animal.sire_id == Animal.id_, Animal.dam_id == >>>> Animal.id)". >>> Thought I was on the right track but now getting the exception below. >>> Here's the model: >>> >>> class Animal(Base): >>> __tablename__ = 'animals' >>> id_ = Column(Integer, primary_key=True) >>> >>> sire_id = Column(Integer, ForeignKey('animals.id_')) >>> dam_id = Column(Integer, ForeignKey('animals.id_')) >>> >>> sire = relationship('Animal', foreign_keys=[sire_id]) >>> dam = relationship('Animal', foreign_keys=[dam_id]) >>> pjoin = 'and_(Animal.sire_id == Animal.id_, Animal.dam_id == Animal.id_)' >>> children = relationship('Animal', foreign_keys=[sire_id, dam_id], >>> primaryjoin=pjoin) >>> >>> So I attempt to put in the first object, which is to be a bit special: >>> >>> unknown = Animal(id_=0) >>> db_session.add(unknown) >>> unknown.sire = unknown # <- get exception here >>> unknown.dam = unknown >>> db_session.commit() >>> >>> TypeError: Incompatible collection type: Animal is not list-like >>> >>> unknown.sire shows to contain [] so it evidently wants a list of sires? >>> That's not what I had in mind for the above model. Any help? >> well here we're doing a self-referential relationship so in order to make a >> many-to-one self ref, as someone else mentioned you need remote_side=sire_id >> >> background: >> >> http://docs.sqlalchemy.org/en/rel_0_9/orm/relationships.html#adjacency-list-relationships >> > Changed model to read: > sire = relationship('Animal', foreign_keys=[sire_id], remote_side=sire_id) > > Same exception: TypeError: Incompatible collection type: Animal is not > list-like > > Also tried it with remote_side=[sire_id], same exception > > Also tried putting it on the 'children' relationship, same exception: > children = relationship('Animal', foreign_keys=[sire_id, dam_id], > primaryjoin=pjoin, remote_side=[sire_id, dam_id]) > > Thanks, > Michael > > > -- > 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 sqlalchemy+unsubscr...@googlegroups.com. > To post to this group, send email to sqlalchemy@googlegroups.com. > 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