I also forgot to mention, the usual workaround here is just to specify
foreign_keys on the relation() manually. so this works:
pj = (child.c.parent_id == parent.c.id) & (child.c.current_id
==child.c.id)
mapper(Child, child,
properties = { 'parent' : relation(Parent,
primaryjoin = pj,
backref = backref("child", primaryjoin=pj,
foreign_keys=[child.c.parent_id]),
foreign_keys=[child.c.parent_id]
),
'current' : relation(Child,primaryjoin =
child.c.current_id ==child.c.id)
})
but still, i dont understand the point of the mapping. youre saying
that Child has a "parent" defined by a join against
child.parent_id==parent.id, *and* the child has its own "current"
element set to itself. so immediately, the operation youre doing in
the test is "wrong": you create a Child, set its Parent, and its
"current" attribute points to nothing, and then you persist it.
loading that data immediately back from a cleared session will produce
None for the parent ! observe:
s = create_session()
c = Child()
c.parent = Parent()
s.save(c)
s.flush()
s.clear()
c = s.query(Child).get(c.id)
print c.parent
the final "lazy" query for c.parent is:
SELECT parent.id AS parent_id, parent.name AS parent_name
FROM parent, child
WHERE ? = parent.id AND child.current_id = child.id ORDER BY parent.oid
and you get: None . just as ordered ! note that if you did *not*
clear the session, no query is issued and then you *do* get the parent
back. this is not a bug in SA, this is just your mapping is designed
to be inconsistent with itself.
So, it seems to me like, instead of having this weird join criterion,
why not just not set the parent against the child in the first place ?
On Nov 6, 2007, at 5:11 AM, Esceo wrote:
>
> Just wondering if this is a bug in _determine_fks
>
> i.e. 'child.id' probably should not be part of the foreign key
> pointing to parent
>
>
> On Nov 6, 7:42 pm, Esceo <[EMAIL PROTECTED]> wrote:
>> Hi, all
>>
>> the followings are the code snippet
>>
>> from sqlalchemy import *
>> meta = MetaData('sqlite://')
>>
>> parent = Table('parent', meta,
>> Column('id', Integer, primary_key=True),
>> Column('name', Integer)
>> )
>>
>> child = Table('child', meta,
>> Column('id', Integer, primary_key=True),
>> Column('current_id', Integer),
>> Column('parent_id', Integer),
>> ForeignKeyConstraint(['parent_id'],['parent.id'],
>> ondelete="CASCADE"),
>> ForeignKeyConstraint(['current_id'],['child.id']), )
>>
>> class Parent(object):
>> pass
>>
>> class Child(object):
>> pass
>>
>> mapper(Parent, parent);
>>
>> mapper(Child, child,
>> properties = { 'parent' : relation(Parent,
>> primaryjoin =
>> (child.c.parent_id == parent.c.id) &
>> (child.c.current_id ==
>> child.c.id),
>> backref = "child"),
>> 'current' : relation(Child,
>> primaryjoin = child.c.current_id ==
>> child.c.id)
>>
>> })
>>
>> meta.create_all()
>>
>> s = create_session()
>> c = Child()
>> c.parent = Parent()
>> s.save(c)
>> s.flush()
>> s.clear()
>>
>> running that resulted in
>>
>> Traceback (most recent call last):
>> File "C:\powerforce\test_fk_relation.py", line 39, in <module>
>> s.flush()
>> File "C:\Python25\lib\site-packages\sqlalchemy-0.3.11dev_r3181-
>> py2.5.egg\sqlalchemy\orm\session.py", line 320, in flush
>> self.uow.flush(self, objects)
>> File "C:\Python25\lib\site-packages\sqlalchemy-0.3.11dev_r3181-
>> py2.5.egg\sqlalchemy\orm\unitofwork.py", line 210, in flush
>> flush_context.execute()
>> File "C:\Python25\lib\site-packages\sqlalchemy-0.3.11dev_r3181-
>> py2.5.egg\sqlalchemy\orm\unitofwork.py", line 400, in execute
>> UOWExecutor().execute(self, head)
>> File "C:\Python25\lib\site-packages\sqlalchemy-0.3.11dev_r3181-
>> py2.5.egg\sqlalchemy\orm\unitofwork.py", line 1018, in execute
>> self.execute_save_steps(trans, task)
>> File "C:\Python25\lib\site-packages\sqlalchemy-0.3.11dev_r3181-
>> py2.5.egg\sqlalchemy\orm\unitofwork.py", line 1035, in
>> execute_save_steps
>> self.execute_dependencies(trans, task, False)
>> File "C:\Python25\lib\site-packages\sqlalchemy-0.3.11dev_r3181-
>> py2.5.egg\sqlalchemy\orm\unitofwork.py", line 1048, in
>> execute_dependencies
>> self.execute_dependency(trans, dep, False)
>> File "C:\Python25\lib\site-packages\sqlalchemy-0.3.11dev_r3181-
>> py2.5.egg\sqlalchemy\orm\unitofwork.py", line 1029, in
>> execute_dependency
>> dep.execute(trans, isdelete)
>> File "C:\Python25\lib\site-packages\sqlalchemy-0.3.11dev_r3181-
>> py2.5.egg\sqlalchemy\orm\unitofwork.py", line 984, in execute
>> self.processor.process_dependencies(self.targettask, [elem.obj for
>> elem in self.targettask.polymorphic_tosave_elements if elem.obj is
>> not
>> None], trans, delete=False)
>> File "C:\Python25\lib\site-packages\sqlalchemy-0.3.11dev_r3181-
>> py2.5.egg\sqlalchemy\orm\dependency.py", line 275, in
>> process_dependencies
>> self._synchronize(obj, child, None, False, uowcommit)
>> File "C:\Python25\lib\site-packages\sqlalchemy-0.3.11dev_r3181-
>> py2.5.egg\sqlalchemy\orm\dependency.py", line 310, in _synchronize
>> self.syncrules.execute(source, dest, obj, child, clearkeys)
>> File "C:\Python25\lib\site-packages\sqlalchemy-0.3.11dev_r3181-
>> py2.5.egg\sqlalchemy\orm\sync.py", line 92, in execute
>> rule.execute(source, dest, obj, child, clearkeys)
>> File "C:\Python25\lib\site-packages\sqlalchemy-0.3.11dev_r3181-
>> py2.5.egg\sqlalchemy\orm\sync.py", line 135, in execute
>> value = self.source_mapper.get_attr_by_column(source,
>> self.source_column)
>> File "C:\Python25\lib\site-packages\SQLAlchemy-0.3.11dev_r3181-
>> py2.5.egg\sqlalchemy\orm\mapper.py", line 1017, in get_attr_by_column
>> prop = self._getpropbycolumn(column, raiseerror)
>> File "C:\Python25\lib\site-packages\SQLAlchemy-0.3.11dev_r3181-
>> py2.5.egg\sqlalchemy\orm\mapper.py", line 1007, in _getpropbycolumn
>> raise exceptions.InvalidRequestError("Column '%s.%s' is not
>> available, due to conflicting property '%s':%s" % (column.table.name,
>> column.name, column.key, repr(prop)))
>> sqlalchemy.exceptions.InvalidRequestError: Column 'child.id' is not
>> available, d
>> ue to conflicting property
>> 'id':<sqlalchemy.orm.properties.ColumnProperty object at 0x016FB730>
>>
>> If I had renamed the id column on child to '_id', I ended up with a
>> different error no child.id column configured on the maper Parent|
>> parent|
>>
>> any clues?
>>
>> Thanks in advance
>>
>> Lei
>
>
> >
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---