I'm still having problems with this (sorry about the huge delay, I got
side-tracked for a while). After creating parent/child/attribute
table rows, I get one of two errors when I try to print
parent.attributes:
If I use the column name "id" in my child table I get this error:
sqlalchemy.exceptions.InvalidRequestError: Column 'child.id' is not
available, due to conflicting property
'id':<sqlalchemy.orm.properties.ColumnProperty object at
0x2b8d77fea410>
Perhaps using "id" is a bad idea? I see most people use something
like "child_id"; I'm just not a fan of the redundancy.
When I use child_id instead I get this error:
sqlalchemy.exceptions.InvalidRequestError: No column child.child_id is
configured on mapper Mapper|Parent|parent...
These exceptions are the two possible error paths when
_getpropbycolumn receives a key error when doing "prop =
self.columntoproperty(column)" (sqlalchemy/orm/mapper.py:983)
Any help would be much appreciated! Here is the code:
from sqlalchemy import *
metadata = BoundMetaData("sqlite:///:memory:")
metadata.engine.echo = True
session = create_session(bind_to = metadata.engine)
parent_table = Table('parent', metadata,
Column('id', Integer, primary_key=True),
Column('name', Unicode),
)
child_table = Table('child', metadata,
Column('child_id', Integer, primary_key=True),
Column('parent_id', Integer, ForeignKey('parent.id')),
)
attribute_table = Table('attribute', metadata,
Column('id', Integer, primary_key=True),
Column('child_id', Integer, ForeignKey('child.child_id')),
)
class Parent(object):
pass
class Child(object):
pass
class Attribute(object):
pass
parent_mapper = mapper(
Parent,
parent_table,
properties = dict(
children = relation(Child, backref='parent'),
attributes = relation(Attribute,
primaryjoin = and_(attribute_table.c.child_id ==
child_table.c.child_id, child_table.c.parent_id == parent_table.c.id),
foreign_keys=[attribute_table.c.child_id],
backref = backref('parent',
foreign_keys=[attribute_table.c.child_id], primaryjoin =
and_(attribute_table.c.child_id == child_table.c.child_id,
child_table.c.parent_id == parent_table.c.id)),
viewonly = True,
)
))
child_mapper = mapper(
Child,
child_table,)
attribute_mapper = mapper(
Attribute,
attribute_table,
properties = dict(
child = relation(Child, backref=backref('attributes'),
viewonly=True),
)
)
metadata.create_all()
parent = Parent()
child = Child()
child.parent = parent
attr = Attribute()
attr.child = child
session.save(parent)
session.flush()
print parent.attributes
On May 24, 10:19 am, Michael Bayer <[EMAIL PROTECTED]> wrote:
> On May 24, 2007, at 10:02 AM, Patrick McKinnon wrote:
>
> > sqlalchemy.exceptions.ArgumentError: Cant locate any foreign key
> > columns in primary join condition 'attribute.child_id = child.id AND
> > child.parent_id = parent.id' for relationship 'Parent.attributes
> > (Attribute)'. Specify 'foreign_keys' argument to indicate which
> > columns in the join condition are foreign.
>
> 0.3.7 is more strict about analyzing relationships and in this case
> nothing in the join condition expresses a foreign key relationship
> between the "parent" and "attribute" table. when only primaryjoin is
> present, it assumes a one-to-many or many-to-one relationship between
> two tables. what youre doing here is trying to "skip" over.
>
> > parent_mapper = mapper(
> > Parent,
> > parent_table,
> > properties = dict(
> > children = relation(Child, backref='parent'),
> > attributes = relation(Attribute,
> > primaryjoin = and_(attribute_table.c.child_id ==
> > child_table.c.id, child_table.c.parent_id == parent_table.c.id),
> > backref = 'parent',
> > )
> > )
> > )
>
> so to "force" it:
>
> parent_mapper = mapper(
> Parent,
> parent_table,
> properties = dict(
> children = relation(Child, backref='parent'),
> attributes = relation(Attribute,
> primaryjoin = and_(attribute_table.c.child_id ==
> child_table.c.id, child_table.c.parent_id == parent_table.c.id),
> foreign_keys=[attribute_table.c.child_id],
> backref = backref('parent', foreign_keys=
> [attribute_table.c.child_id], primaryjoin = and_
> (attribute_table.c.child_id ==
> child_table.c.id, child_table.c.parent_id ==
> parent_table.c.id),),
> )
> )
> )
>
> however you want to put "viewonly=True" for the "attributes"
> relationship, since that relationship will not persist correctly at all.
>
> the "correct" way would be to just deal with the attributes
> explicitly as they are attached to each child object. Normally id
> try to use the "associationproxy" extension here but your
> "attributes" property is actually the product of many individual
> Child objects which is a little unusual.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---