声明式 SQLAlchemy 关系()的入门问题

Posted

技术标签:

【中文标题】声明式 SQLAlchemy 关系()的入门问题【英文标题】:Starter question of declarative style SQLAlchemy relation() 【发布时间】:2011-02-06 22:35:22 【问题描述】:

我对 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 类中有两个外键,因此relation() 调用无法确定应该使用哪一个。我想我必须使用额外的参数来指定它,对吧? 怎么做?谢谢

【问题讨论】:

【参考方案1】:

正确的语法应该是:

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

附:下次请通过发布回溯来说明“无法运行”是什么意思。

更新:更新问题中的回溯准确地说明了您的需求:指定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))

【讨论】:

感谢您的建议。错字已被修正,并已追加回溯。

以上是关于声明式 SQLAlchemy 关系()的入门问题的主要内容,如果未能解决你的问题,请参考以下文章

在 SQLAlchemy 中处理插入时重复的主键(声明式样式)

SQLAlchemy 声明式:定义触发器和索引 (Postgres 9)

如何使用 SQLAlchemy 声明性语法指定关系?

SQLAlchemy 如何使用声明性映射一对一关系的单列

SQLAlchemy - 将自引用关系映射为一对多(声明形式)

SQLAlchemy 通过关联对象声明性多对多自联接