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.

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

Reply via email to