我正在尝试做与以下示例类似的事情:
http://docs.sqlalchemy.org/en/rel_0_8/orm/relationships.html#handling-multiple-join-paths
当我执行以下脚本时:
#!/usr/bin/python
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship, backref
from sqlalchemy.orm import aliased
engine = create_engine('sqlite:///demo.db', echo=True)
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
fullname = Column(String)
password = Column(String)
def __init__(self, name, fullname, password):
self.name = name
self.fullname = fullname
self.password = password
def __repr__(self):
return "<User('%s','%s', '%s')>" % (self.name, self.fullname, self.password)
class Address(Base):
__tablename__ = 'addresses'
id = Column(Integer, primary_key=True)
email_address = Column(String, nullable=False)
user_id = Column(Integer, ForeignKey('users.id'))
user = relationship("User", backref=backref('addresses', order_by=id), passive_deletes=True)
user2 = relationship("User", backref=backref('addresses2', order_by=id), passive_deletes=True)
def __init__(self, email_address):
self.email_address = email_address
def __repr__(self):
return "<Address('%s')>" % self.email_address
class Customer(Base):
__tablename__ = 'customer'
id = Column(Integer, primary_key=True)
name = Column(String)
billing_address_id = Column(Integer, ForeignKey("addresses.id"))
shipping_address_id = Column(Integer, ForeignKey("addresses.id"))
billing_address = relationship("Address", foreign_keys=[billing_address_id])
shipping_address = relationship("Address", foreign_keys=[shipping_address_id])
def test():
print "Testing .."
# Test code.
if __name__ == '__main__':
test()
我明白了
2013-06-30 12:56:53,938 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("users")
2013-06-30 12:56:53,938 INFO sqlalchemy.engine.base.Engine ()
2013-06-30 12:56:53,939 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("addresses")
2013-06-30 12:56:53,940 INFO sqlalchemy.engine.base.Engine ()
2013-06-30 12:56:53,940 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("customer")
2013-06-30 12:56:53,940 INFO sqlalchemy.engine.base.Engine ()
Traceback (most recent call last):
File "./test.py", line 131, in <module>
test()
File "./test.py", line 70, in test
ed_user = User('ed', 'Ed Jones', 'edspassword')
File "<string>", line 2, in __init__
File "/usr/lib/python2.7/dist-packages/sqlalchemy/orm/instrumentation.py", line 309, in _new_state_if_none
state = self._state_constructor(instance, self)
File "/usr/lib/python2.7/dist-packages/sqlalchemy/util/langhelpers.py", line 494, in __get__
obj.__dict__[self.__name__] = result = self.fget(obj)
File "/usr/lib/python2.7/dist-packages/sqlalchemy/orm/instrumentation.py", line 157, in _state_constructor
self.dispatch.first_init(self, self.class_)
File "/usr/lib/python2.7/dist-packages/sqlalchemy/event.py", line 377, in __call__
fn(*args, **kw)
File "/usr/lib/python2.7/dist-packages/sqlalchemy/orm/mapper.py", line 2347, in _event_on_first_init
configure_mappers()
File "/usr/lib/python2.7/dist-packages/sqlalchemy/orm/mapper.py", line 2263, in configure_mappers
mapper._post_configure_properties()
File "/usr/lib/python2.7/dist-packages/sqlalchemy/orm/mapper.py", line 1172, in _post_configure_properties
prop.init()
File "/usr/lib/python2.7/dist-packages/sqlalchemy/orm/interfaces.py", line 128, in init
self.do_init()
File "/usr/lib/python2.7/dist-packages/sqlalchemy/orm/properties.py", line 911, in do_init
self._determine_joins()
File "/usr/lib/python2.7/dist-packages/sqlalchemy/orm/properties.py", line 1048, in _determine_joins
% self)
sqlalchemy.exc.ArgumentError: Could not determine join condition between parent/child tables on relationship Customer.billing_address. Specify a 'primaryjoin' expression. If 'secondary' is present, 'secondaryjoin' is needed as well.
我希望该示例能够开箱即用,并且不必将primaryjoin作为参数添加到relationship()。