Начальный вопрос о декларативном стиле отношения SQLAlchemy () - PullRequest
5 голосов
/ 12 апреля 2010

Я новичок в SQLAlchemy, или даже в программировании баз данных, возможно, мой вопрос слишком прост. Теперь у меня есть два класса / таблицы:

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(40))
    ...

class Computer(Base):
    __tablename__ = 'comps'
    id = Column(Integer, primary_key=True)
    buyer_id = Column(None, ForeignKey('users.id'))
    user_id = Column(None, ForeignKey('users.id'))
    buyer = relation(User, backref=backref('buys', order_by=id))
    user = relation(User, backref=backref('usings', order_by=id))

Конечно, он не может работать. Это обратный след:

  File "/Library/Python/2.6/site-packages/SQLAlchemy-0.5.8-py2.6.egg/sqlalchemy/orm/state.py", line 71, in initialize_instance
    fn(self, instance, args, kwargs)
  File "/Library/Python/2.6/site-packages/SQLAlchemy-0.5.8-py2.6.egg/sqlalchemy/orm/mapper.py", line 1829, in _event_on_init
    instrumenting_mapper.compile()
  File "/Library/Python/2.6/site-packages/SQLAlchemy-0.5.8-py2.6.egg/sqlalchemy/orm/mapper.py", line 687, in compile
    mapper._post_configure_properties()
  File "/Library/Python/2.6/site-packages/SQLAlchemy-0.5.8-py2.6.egg/sqlalchemy/orm/mapper.py", line 716, in _post_configure_properties
    prop.init()
  File "/Library/Python/2.6/site-packages/SQLAlchemy-0.5.8-py2.6.egg/sqlalchemy/orm/interfaces.py", line 408, in init
    self.do_init()
  File "/Library/Python/2.6/site-packages/SQLAlchemy-0.5.8-py2.6.egg/sqlalchemy/orm/properties.py", line 716, in do_init
    self._determine_joins()
  File "/Library/Python/2.6/site-packages/SQLAlchemy-0.5.8-py2.6.egg/sqlalchemy/orm/properties.py", line 806, in _determine_joins
    "many-to-many relation, 'secondaryjoin' is needed as well." % (self))
sqlalchemy.exc.ArgumentError: Could not determine join condition between parent/child tables on relation Package.maintainer.  Specify a 'primaryjoin' expression.  If this is a many-to-many relation, 'secondaryjoin' is needed as well.

В классе Computer есть два внешних ключа, поэтому вызовы отношения () не могут определить, какой из них следует использовать. Я думаю, что я должен использовать дополнительные аргументы, чтобы указать это, верно? И как? Спасибо

1 Ответ

10 голосов
/ 12 апреля 2010

Правильный синтаксис должен быть:

buyer = relation(User, backref=backref('buys', order_by=id))
user = relation(User, backref=backref('usings', order_by=id))

P.S. В следующий раз укажите, что вы подразумеваете под словом «невозможно запустить», опубликовав трассировку.

Обновление : трассировка в обновленном вопросе говорит именно то, что вам нужно: укажите primaryjoin условие:

buyer = relation(User, primaryjoin=(buyer_id==User.id),
                 backref=backref('buys', order_by=id))
user = relation(User, primaryjoin=(user_id==User.id),
                backref=backref('usings', order_by=id))
...