I'm getting a strange error when I specify primaryjoin in relation().
Here's a short script to reproduce the error:
#!/usr/bin/env python
from sqlalchemy import *
from sqlalchemy.types import *
from sqlalchemy.orm import *
engine = create_engine('sqlite:///:memory:', echo=True)
metadata = MetaData()
table1 = Table('table1', metadata,
Column('id', Integer, primary_key=True),
Column('name', Unicode()),
)
table2 = Table('table2', metadata,
Column('id', Integer, primary_key=True),
Column('name', Unicode()),
Column('left', Integer, ForeignKey('table1.id')),
Column('right', Integer, ForeignKey('table1.id')),
)
class Table1(object):
def __init__(self, name):
self.name = name
class Table2(object):
def __init__(self, name, left, right):
self.name = name
self.left = left
self.right = right
mapper(Table1, table1, properties={
'left_of':relation(Table2,
primaryjoin=table1.c.id==table2.c.left),
'right_of':relation(Table2,
primaryjoin=table1.c.id==table2.c.right),
})
mapper(Table2, table2, properties={
'left':relation(Table1,
primaryjoin=table1.c.id==table2.c.left),
'right':relation(Table1,
primaryjoin=table1.c.id==table2.c.right),
}, allow_column_override=True)
metadata.drop_all(engine)
metadata.create_all(engine)
Session = sessionmaker(bind=engine, autoflush=True,
transactional=True)
session = Session()
a = Table1('a')
session.save(a)
b = Table1('b')
session.save(b)
c = Table2('c', a, b)
session.save(c)
session.commit()
Here's the error I get:
2007-12-28 21:43:36,070 INFO sqlalchemy.engine.base.Engine.0x..cL
PRAGMA table_info("table2")
2007-12-28 21:43:36,071 INFO sqlalchemy.engine.base.Engine.0x..cL {}
2007-12-28 21:43:36,072 INFO sqlalchemy.engine.base.Engine.0x..cL
PRAGMA table_info("table1")
2007-12-28 21:43:36,072 INFO sqlalchemy.engine.base.Engine.0x..cL {}
2007-12-28 21:43:36,074 INFO sqlalchemy.engine.base.Engine.0x..cL
PRAGMA table_info("table1")
2007-12-28 21:43:36,075 INFO sqlalchemy.engine.base.Engine.0x..cL {}
2007-12-28 21:43:36,076 INFO sqlalchemy.engine.base.Engine.0x..cL
PRAGMA table_info("table2")
2007-12-28 21:43:36,076 INFO sqlalchemy.engine.base.Engine.0x..cL {}
2007-12-28 21:43:36,078 INFO sqlalchemy.engine.base.Engine.0x..cL
CREATE TABLE table1 (
id INTEGER NOT NULL,
name TEXT,
PRIMARY KEY (id)
)
2007-12-28 21:43:36,078 INFO sqlalchemy.engine.base.Engine.0x..cL {}
2007-12-28 21:43:36,079 INFO sqlalchemy.engine.base.Engine.0x..cL
COMMIT
2007-12-28 21:43:36,081 INFO sqlalchemy.engine.base.Engine.0x..cL
CREATE TABLE table2 (
id INTEGER NOT NULL,
name TEXT,
"left" INTEGER,
"right" INTEGER,
PRIMARY KEY (id),
FOREIGN KEY("left") REFERENCES table1 (id),
FOREIGN KEY("right") REFERENCES table1 (id)
)
2007-12-28 21:43:36,082 INFO sqlalchemy.engine.base.Engine.0x..cL {}
2007-12-28 21:43:36,083 INFO sqlalchemy.engine.base.Engine.0x..cL
COMMIT
2007-12-28 21:43:36,117 INFO sqlalchemy.engine.base.Engine.0x..cL
BEGIN
2007-12-28 21:43:36,119 INFO sqlalchemy.engine.base.Engine.0x..cL
INSERT INTO table1 (name) VALUES (?)
2007-12-28 21:43:36,120 INFO sqlalchemy.engine.base.Engine.0x..cL
['a']
2007-12-28 21:43:36,131 INFO sqlalchemy.engine.base.Engine.0x..cL
INSERT INTO table1 (name) VALUES (?)
2007-12-28 21:43:36,132 INFO sqlalchemy.engine.base.Engine.0x..cL
['b']
2007-12-28 21:43:36,133 INFO sqlalchemy.engine.base.Engine.0x..cL
ROLLBACK
Traceback (most recent call last):
File "/home/jgardner/tmp/sqlalchemy-error.py", line 57, in <module>
session.commit()
File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.4.1-py2.5.egg/
sqlalchemy/orm/session.py", line 483, in commit
self.transaction = self.transaction.commit()
File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.4.1-py2.5.egg/
sqlalchemy/orm/session.py", line 210, in commit
self.session.flush()
File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.4.1-py2.5.egg/
sqlalchemy/orm/session.py", line 683, in flush
self.uow.flush(self, objects)
File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.4.1-py2.5.egg/
sqlalchemy/orm/unitofwork.py", line 209, in flush
flush_context.execute()
File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.4.1-py2.5.egg/
sqlalchemy/orm/unitofwork.py", line 436, in execute
UOWExecutor().execute(self, head)
File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.4.1-py2.5.egg/
sqlalchemy/orm/unitofwork.py", line 1055, in execute
self.execute_save_steps(trans, task)
File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.4.1-py2.5.egg/
sqlalchemy/orm/unitofwork.py", line 1072, in execute_save_steps
self.execute_dependencies(trans, task, False)
File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.4.1-py2.5.egg/
sqlalchemy/orm/unitofwork.py", line 1085, in execute_dependencies
self.execute_dependency(trans, dep, False)
File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.4.1-py2.5.egg/
sqlalchemy/orm/unitofwork.py", line 1066, in execute_dependency
dep.execute(trans, isdelete)
File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.4.1-py2.5.egg/
sqlalchemy/orm/unitofwork.py", line 1021, 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 "/usr/lib/python2.5/site-packages/SQLAlchemy-0.4.1-py2.5.egg/
sqlalchemy/orm/dependency.py", line 282, in process_dependencies
self._synchronize(obj, child, None, False, uowcommit)
File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.4.1-py2.5.egg/
sqlalchemy/orm/dependency.py", line 317, in _synchronize
self.syncrules.execute(source, dest, obj, child, clearkeys)
File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.4.1-py2.5.egg/
sqlalchemy/orm/sync.py", line 91, in execute
rule.execute(source, dest, obj, child, clearkeys)
File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.4.1-py2.5.egg/
sqlalchemy/orm/sync.py", line 143, in execute
self.dest_mapper.set_attr_by_column(dest, self.dest_column, value)
File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.4.1-py2.5.egg/
sqlalchemy/orm/mapper.py", line 931, in set_attr_by_column
self._columntoproperty[column].setattr(obj, value, column)
File "/usr/lib/python2.5/site-packages/SQLAlchemy-0.4.1-py2.5.egg/
sqlalchemy/orm/util.py", line 101, in __getitem__
return super(TranslatingDict,
self).__getitem__(self.__translate_col(col))
KeyError: Column('left', Integer(), ForeignKey('table1.id'))
If I don't specify primaryjoin, everything's okay--as long as it is
obvious how the two tables join. In this case, since it is not
obvious, primaryjoin is necessary.
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---