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 <[email protected]> wrote:
> On 2/14/2014 11:50 AM, Michael Bayer wrote:
>> On Feb 14, 2014, at 12:46 PM, Michael Hipp <[email protected]> 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 [email protected].
> To post to this group, send email to [email protected].
> 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
