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 sqlalchemy@googlegroups.com
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to