SQLAlchemy同时一对一和一对多(AmbiguousForeignKeysError)

时间:2014-08-24 17:59:43

标签: python postgresql orm sqlalchemy

我正在使用SQLAlchemy,我尝试在同一个父类上实现一对一和一对多的关系。 这是为了简单地跟踪主要子实体。

不幸的是我收到了错误:

  

AmbiguousForeignKeysError:无法确定之间的连接条件   关系Customer.contact上的父/子表 - 有   链接表的多个外键路径。指定   ' foreign_keys'参数,提供那些列的列表   应计为包含对父项的外键引用   表

我做错了什么或不可能?

这是一个代码示例:

class Customer(Base):

    __tablename__ = 'customer'

    id = Column(Integer, primary_key=True)
    contact_id = Column(Integer, ForeignKey('contact.id'))
    address_id = Column(Integer, ForeignKey('address.id'))

    contact = relationship('Contact', backref=backref("contact", uselist=False))
    address = relationship('Address', backref=backref("address", uselist=False))

    contact_list = relationship('Contact')
    address_list = relationship('Address')


class Contact(Base):

    __tablename__ = 'contact'

    id = Column(Integer, primary_key=True)
    customer_id = Column(Integer, ForeignKey(
        'customer.id',
        use_alter=True, name='fk_contact_customer_id_customer',
        onupdate='CASCADE', ondelete='SET NULL'
    ))
    first_name = Column(String(32))
    last_name = Column(String(32))


class Address(Base):

    __tablename__ = 'address'

    id = Column(Integer, primary_key=True)
    customer_id = Column(Integer, ForeignKey(
        'customer.id',
        use_alter=True, name='fk_address_customer_id_customer',
        onupdate='CASCADE', ondelete='SET NULL'
    ))
    label = Column(String(32))

由于

1 个答案:

答案 0 :(得分:3)

显然这个解决方案后来在documentation: SQLAlchemy不知道要使用哪个外键,因此您必须在Column中将这些对象指定为relationship(foreign_keys=[]),如下所示:

class Contact(Base):
    # ...
    customer_id = Column(Integer, ForeignKey(
        'customer.id',
        use_alter=True, name='fk_contact_customer_id_customer',
        onupdate='CASCADE', ondelete='SET NULL'
    ))
    # ...


class Customer(Base):
    # ...
    contact_id = Column(Integer, ForeignKey('contact.id'))
    #...
    contact = relationship('Contact', uselist=False, foreign_keys=[contact_id])
    contact_list = relationship('Contact', foreign_keys=[Contact.customer_id])
    #...