On Wed, Nov 17, 2010 at 1:16 AM, Michael Bayer <[email protected]> wrote: > ForeignKeyConstraint needs to go into __table_args__ when using declarative. > > http://www.sqlalchemy.org/docs/orm/extensions/declarative.html#table-configuration
Thanks for the note. I have updated my test script to use __table_args__ but the error remains the same (see script and ouput below). I then tried with the hybrid approach (http://www.sqlalchemy.org/docs/orm/extensions/declarative.html#using-a-hybrid-approach-with-table) which works well. Am I again doing something wrong with declarative ? Thanks, ################################# from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class Foo(Base): __tablename__ = "foo" one = Column(Integer, primary_key=True) two = Column(Integer, primary_key=True) class Bar(Base): __tablename__ = "bar" __table_args__ = ( ForeignKeyConstraint(['one_id', 'two_id'], ['foo.one', 'foo.two']) ) id = Column(Integer, primary_key=True) one_id = Column(Integer, nullable=False) two_id = Column(Integer, nullable=False) foo = relationship("Foo", backref = "bars") metadata = Base.metadata engine = create_engine('sqlite:///:memory:', echo=True) metadata.create_all(engine) from sqlalchemy.orm import sessionmaker # create a configured "Session" class Session = sessionmaker(bind=engine) # create a Session session = Session() foo = Foo() foo.one = 1 foo.two = 2 session.add(foo) session.commit() ############################# 2010-11-17 14:56:01,309 INFO sqlalchemy.engine.base.Engine.0x...9690 PRAGMA table_info("foo") 2010-11-17 14:56:01,309 INFO sqlalchemy.engine.base.Engine.0x...9690 () 2010-11-17 14:56:01,310 INFO sqlalchemy.engine.base.Engine.0x...9690 PRAGMA table_info("bar") 2010-11-17 14:56:01,310 INFO sqlalchemy.engine.base.Engine.0x...9690 () 2010-11-17 14:56:01,310 INFO sqlalchemy.engine.base.Engine.0x...9690 CREATE TABLE foo ( one INTEGER NOT NULL, two INTEGER NOT NULL, PRIMARY KEY (one, two) ) 2010-11-17 14:56:01,310 INFO sqlalchemy.engine.base.Engine.0x...9690 () 2010-11-17 14:56:01,310 INFO sqlalchemy.engine.base.Engine.0x...9690 COMMIT 2010-11-17 14:56:01,311 INFO sqlalchemy.engine.base.Engine.0x...9690 CREATE TABLE bar ( id INTEGER NOT NULL, one_id INTEGER NOT NULL, two_id INTEGER NOT NULL, PRIMARY KEY (id) ) 2010-11-17 14:56:01,311 INFO sqlalchemy.engine.base.Engine.0x...9690 () 2010-11-17 14:56:01,311 INFO sqlalchemy.engine.base.Engine.0x...9690 COMMIT Traceback (most recent call last): File "compositePrimaryKey_decl.py", line 39, in <module> foo = Foo() File "<string>", line 4, in __init__ File "/home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/state.py", line 93, in initialize_instance fn(self, instance, args, kwargs) File "/home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/mapper.py", line 2357, in _event_on_init instrumenting_mapper.compile() File "/home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/mapper.py", line 805, in compile mapper._post_configure_properties() File "/home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/mapper.py", line 834, in _post_configure_properties prop.init() File "/home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/interfaces.py", line 493, in init self.do_init() File "/home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/properties.py", line 840, in do_init self._determine_joins() File "/home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/properties.py", line 969, in _determine_joins % self) sqlalchemy.exc.ArgumentError: Could not determine join condition between parent/child tables on relationship Bar.foo. Specify a 'primaryjoin' expression. If this is a many-to-many relationship, 'secondaryjoin' is needed as well. The script below works with the hybrid declarative approach: ################################# from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class Foo(Base): __tablename__ = "foo" one = Column(Integer, primary_key=True) two = Column(Integer, primary_key=True) bartable = Table("bar", Base.metadata, Column("id", Integer, primary_key=True), Column("one_id", Integer, nullable=False), Column("two_id", Integer, nullable=False), ForeignKeyConstraint(['one_id', 'two_id'], ['foo.one', 'foo.two']), ) class Bar(Base): __table__ = bartable foo = relationship("Foo", backref = "bars") metadata = Base.metadata engine = create_engine('sqlite:///:memory:', echo=True) metadata.create_all(engine) from sqlalchemy.orm import sessionmaker # create a configured "Session" class Session = sessionmaker(bind=engine) # create a Session session = Session() foo = Foo() foo.one = 1 foo.two = 2 session.add(foo) session.commit() bar = Bar() bar.foo = foo session.add(bar) session.commit() ############################# -- 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.
