Michael,

Thank you for the answer,  I have been "wasting" my time all day getting this 
to work, reading documents etc. Since I'm a low level programmer I'm not really 
into database programming, The article you pointed out is not really 
understandable by me because of this.

I did the following (I left out the "other" definitions:

class Relation(Base):
    __tablename__               = 'relations'
    RId                                 = Column(Integer, 
ForeignKey('affiliations.Id'), primary_key=True) # primary_key is just to make 
SQLA happy about the PK needed
    LId                                 = Column(Integer, 
ForeignKey('affiliations.Id'))
    
class Affiliation(Base):
    __tablename__               = "affiliations"
    Id                                          = Column(Integer, 
primary_key=True)
    discriminator                       = Column('type', Unicode(20))
    __mapper_args__             = {'polymorphic_on': discriminator}
    ParentRelation                      = 
relation('Affiliation',primaryjoin='Relation.LId == Affiliation.Id', 
secondary=Relation.__table__)
    ChildRelation               = 
relation('Affiliation',primaryjoin='Relation.RId == Affiliation.Id', 
secondary=Relation.__table__)

This trows the error: sqlalchemy.exc.ArgumentError: Could not determine join 
condition between parent/child tables on relation Affiliation.ChildRelation.  
Specify a 'primaryjoin' expression.  If this is a many-to-many relation, 
'secondaryjoin' is needed as well.

I tried it with the table definition not declerative:

rel = Table('relations', Base.metadata, 
Column('RId', Integer, ForeignKey('affiliations.Id')),
Column('LId', Integer, ForeignKey('affiliations.Id'))) 
        
class Affiliation(Base):
    __tablename__               = "affiliations"
    Id                                  = Column(Integer, primary_key=True)
    discriminator               = Column('type', Unicode(20))
    __mapper_args__     = {'polymorphic_on': discriminator}
    ParentRelation              = 
relation('Affiliation',primaryjoin='relations.LId == Affiliation.Id', 
secondary=rel)
    ChildRelation               = 
relation('Affiliation',primaryjoin='relations.RId == Affiliation.Id', 
secondary=rel)

And this throws: AttributeError: 'Table' object has no attribute 'LId'
(Once I create an Instance of Company like z=Company(), see the definition 
below)

I also did put the relation definition in the __init__ of the Affiliation class 
(with :

        def __init__(self):
                self.ParentRelation             = 
relation('Affiliation',primaryjoin='Relation.LId == Affiliation.Id', 
secondary=Relation.__table__)
                self.ChildRelation                      = 
relation('Affiliation',primaryjoin='Relation.RId == Affiliation.Id', 
secondary=Relation.__table__)


This seems to work, but:

p1 = Person()     (see below)
z = Company() (see below)

Traceback (most recent call last):
  File "/Users/martijn/pywebos/Affiliation/AffiliationMain.py", line 126, in 
<module>
    z.ParentRelation.append(p1)
AttributeError: 'RelationProperty' object has no attribute 'append'


I'm puzzled, sorry....

Any suggestions?

Martijn



On Jan 4, 2011, at 4:30 PM, Michael Bayer wrote:

> 
> I don't see why the relationship between two Affiliation subclasses can't be 
> self-referencing.    You'd add another column to "affiliations" with a name 
> like "related_to", use relationship() with primaryjoin.   If you model the 
> relationship as simply Affiliation->Affiliation then that single relationship 
> handles the linkage for all subclass combinations.    
> 
> If you'd rather have the linkages on the "persons" and "companies" tables, 
> that is also fine, you just need to use two separate relationships to manage 
> each foreign key, one local to "persons" the other local to "companies".
> 
> Even if you use an association table, as long as the linkages are from 
> Affiliation->Affiliation, no weird gymnastics with "relationtypes" should be 
> needed for persistence/querying.   
> 
> This may or may not be related but this seems to have some elements which 
> resemble a "polymorphic association", which is described at: 
> http://techspot.zzzeek.org/2007/05/29/polymorphic-associations-with-sqlalchemy/
>  , perhaps that can shed some light as well.
> 
> 
> 
> 
> On Jan 4, 2011, at 7:54 AM, Martijn Moeling wrote:
> 
>> Update, (Still need help, I'm really puzzled on how to do this)
>> 
>> since both Person and Company are polymorphic from Affiliation the relations 
>> are not really self referencing,
>> 
>> So I need help defining the relation and a reference table. The reference 
>> table should however be something like this:
>> 
>> 
>> 
>> TablenameL        LId           TablenameR   Rid
>> 
>> person                       1               company                 2
>> company              2               person                  3
>> 
>> So the reference table "relations" should have a compound key "person:1" to 
>> connect to "company:2"
>> at the same time "company:2" should connect to "person:3"
>> 
>> I would like to add something like this to my Affiliation class:
>> 
>>   relationships       = 
>> relation(Relation,primaryjoin=or_(and_(Relation.LTable==discriminator,Relation.LId
>>  ==Id),and_(Relation.RTable==discriminator,Relation.RId==Id)))
>> 
>> I know this is wrong but the reference table should also work backwards. 
>> There will also be an Relationtype indicating 
>> 
>> Company->employee->Person, 
>> Company->customer->Person
>> Person->friend-Person
>> 
>> etc. (one Company can have many relations to the same Person, like Companies 
>> can have multiple relations with other companies (like "supplier", 
>> "customer", "partner (like in a project)" etc. etc)
>> 
>> also Person1->Father->Person2 will be Person2->Son->Person1 when lookup the 
>> other way around. the Relationtype will be a ForeignKey to another table, 
>> the "Order" will be dependent on the "side" of the (current object) Person 
>> so there might be two relations in the Affiliation object . One working on 
>> the "Left" side of the reference table and the other one from the "Right"
>> 
>> This is just a small piece, in total there are many Classes based on the 
>> Affiliation object so doing it all there would be nice....
>> 
>> Thanks for ANY thoughts, doing this right from the beginning helps me a lot. 
>> The definition of Affiliation, Person and Company can be found below.
>> 
>> Martijn
>> 
>> On Jan 4, 2011, at 9:55 AM, Martijn Moeling wrote:
>> 
>>> Hi
>>> 
>>> I have done the following:
>>> 
>>> 
>>> class Affiliation(Base):
>>>  __tablename__       = "affiliations"
>>>  Id                  = Column(Integer, primary_key=True)
>>>  FullName            = Column(Unicode(255), index = True)
>>>  discriminator       = Column('type', Unicode(20))
>>>  __mapper_args__     = {'polymorphic_on': discriminator}
>>> 
>>> 
>>> class Person(Affiliation):
>>>  __tablename__       = 'persons'
>>>  __mapper_args__     = {'polymorphic_identity' : u'person'} 
>>>  Id                  = Column(Integer,ForeignKey('affiliations.Id'), 
>>> primary_key=True)
>>> 
>>> 
>>> class Company(Affiliation):
>>>  __tablename__       = 'companies'
>>>  __mapper_args__     = {'polymorphic_identity' : u'company'} 
>>>  Id                  = Column(Integer,ForeignKey('affiliations.Id'), 
>>> primary_key=True)
>>> 
>>> which is straight foreward.
>>> 
>>> What I want do do now is a bit more troublesome, I have been trying many 
>>> different things but....
>>> 
>>> class relation(Base):
>>> 
>>> Parent              =   reference to one of the Affiliations
>>> Child               =   reference to one of the Affiliations
>>> Relation_type = column(Integer)                              (like two 
>>> persons can be Father and Son, Two companies can be supplier and customer)
>>> 
>>> 
>>> It would be very nice if I can change the Affiliation class to self 
>>> reference M:N
>>> 
>>> Problem with this is that both Parent and child (or "left and right "side") 
>>> have to be checked and updated
>>> 
>>> Martijn
>>> 
>>> -- 
>>> You received this message because you are subscribed to the Google Groups 
>>> "sqlalchemy" group.
>>> To post to this group, send email to sqlalch...@googlegroups.com.
>>> To unsubscribe from this group, send email to 
>>> sqlalchemy+unsubscr...@googlegroups.com.
>>> For more options, visit this group at 
>>> http://groups.google.com/group/sqlalchemy?hl=en.
>>> 
>> 
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "sqlalchemy" group.
>> To post to this group, send email to sqlalch...@googlegroups.com.
>> To unsubscribe from this group, send email to 
>> sqlalchemy+unsubscr...@googlegroups.com.
>> For more options, visit this group at 
>> http://groups.google.com/group/sqlalchemy?hl=en.
>> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To post to this group, send email to sqlalch...@googlegroups.com.
> To unsubscribe from this group, send email to 
> sqlalchemy+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/sqlalchemy?hl=en.
> 

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to