thanks for the patch, I will look into checking it in tonight with a
few tweaks.
The error you are getting has to do with the fact that the syntax:
relation(class, table, **keyword_args)
will always create a brand new mapper on the given class/table
combination. So in effect you are creating three mappers for Subject/
subject and it gets all wacked out because the "non-primary" mappers,
i.e. mappers #2 and #3, are trying to add new properties to the
class, and I recently added an assertion to prevent this from
happening since its the primary mapper that determines most of the
behavior on the class, including dependency calculation, and theres
no reason you would actually want to make secondary mappers with new
object properties on them....it would invariably lead to bigger
problems.
So when you create a relation, there are two syntaxes you can use to
get a hold of the "primary" mapper:
relation(class, **keyword_args)
or
relation(mapper, **keyword_args)
For a self-referential relationship, the former is easiest since its
useable within the construction of the mapper itself..it gets a hold
of the class's primary mapper after everything has been connected.
This syntax is admittedly a little bit subtle and I am open to
reworking it. I am not sure if I want to let go of the "create a
relation and a mapper in one shot" idea, but it seems less of a
common pattern than I originally thought it would be.
The second issue is that the "foreignkey" property needs to point in
the other direction for it to determine "many-to-one"; i.e. im a
Subject, and my "parent1o" attribute points to "subject.id" over
there. Honestly the whole which-way-to-point things question
confuses the blazes out of me, and while writing this thing I was
fortunate that theres only two choices for most of those questions.
So I often point things the wrong way and when they dont work, I just
switch them, spend 5 minutes trying to visualize why, then i just get
confused again when i look at it the next day. outside of the self-
referential relationship, you dont really have to deal with it. but
maybe i can think of a way to make that easier.
Anyway, a full version of test.py with the above fixes is attached
and it seems to create the data I think you are looking for.
from sqlalchemy import *
engine = create_engine('sqlite://', echo=True)
subjects = Table('subject', engine,
Column('id', Integer, primary_key=True),
Column('parent1', Integer, ForeignKey('subject.id')),
Column('parent2', Integer, ForeignKey('subject.id')),
)
subjects.create()
class Subject(object):
pass
mapper = mapper(Subject, subjects,
properties={
'parent1o':relation(Subject,
primaryjoin=(subjects.c.id==subjects.c.parent1),
foreignkey=subjects.c.id),
'parent2o':relation(Subject,
primaryjoin=(subjects.c.id==subjects.c.parent2),
foreignkey=subjects.c.id),
}
)
Subject.mapper = mapper
s = Subject()
s.parent1o = Subject()
s.parent2o = Subject()
objectstore.commit()
l = subjects.select().execute().fetchall()
print l
- mike
On Jan 4, 2006, at 8:19 PM, [EMAIL PROTECTED] wrote:
Hi,
I'm wondering if someone could provide an example
of "self-joins" via the ORM/mapper? I'm attaching
a code sample to illustrate what I've tried below.
The current error that I get is:
Non-primary property created for attribute 'parent2o' on class
'Subject', but that attribute is not managed! Insure that the
primary mapper for this class defines this property: None
It appears that my code implicitly creates two
mapper objects, based on pdb.pm() inspection.
I'm not sure how the mapper_registry/hashkey
get managed and initialized, so I couldn't move
forward with debugging.
I am also using namespace schemas, and believe
that there is a problem with ForeignKey objects
not handling namespace schemas. I am attaching
a patch for that.
(I have simplified the attached test.py to not
use namespace schemas).
Thanks,
Daishi
<test.py>
<schema.diff>