SQLAlchemy:通过辅助表为同表关系建模

时间:2019-11-05 03:20:04

标签: python sqlalchemy flask-sqlalchemy

我有一个products表,我想在产品之间建立关系(即“您可能也喜欢这些产品...”)

有一个名为product_related的辅助表,其中包含数据。如何在SQLAlchemy中对此建模?

  

产品

-----------------------------
| skuid | name              |
-----------------------------
| B1234 | Test Product 1    |
-----------------------------
| B1235 | Test Product 2    |
-----------------------------
| B1236 | Test Product 3    |
-----------------------------
  

与产品相关

--------------------
| skuid | related  |
--------------------
| B1234 | B1235    |
--------------------
| B1234 | B1236    |
--------------------
| B1235 | B1234    |
--------------------
| B1235 | B1236    |
--------------------
| B1236 | B1234    |
--------------------
| B1236 | B1235    |
--------------------

我的尝试(使用flask-sqlalchemy)是:

class Product(db.Model):
    __tablename__ = 'products'

    skuid = db.Column(db.String(16), primary_key=True)
    name = db.Column(db.String(128))
    related = db.relationship("Product", secondary="product_related")

class ProductToRelated(db.Model):
    __tablename__ = 'product_related'

    skuid = db.Column(db.String(36), db.ForeignKey('products.skuid'), nullable=False)
    related_skuid = db.Column(db.String(36), db.ForeignKey('products.skuid'), nullable=False)

    product = db.relationship('Product', foreign_keys="ProductToRelated.skuid")
    related_product = db.relationship('Product', foreign_keys="ProductToRelated.related_skuid")

我得到的错误是:

sqlalchemy.exc.AmbiguousForeignKeysError: Could not determine join condition between parent/child tables on relationship Product.related - there are multiple foreign key paths linking the tables via secondary table 'product_related'.  Specify the 'foreign_keys' argument, providing a list of those columns which should be counted as containing a foreign key reference from the secondary table to each of the parent and child tables. 

1 个答案:

答案 0 :(得分:1)

该错误的原因是ProductToRelated中有两个到Product的外键,因此,除非明确说明,否则该关系无法确定要使用哪个关系。以下应该起作用。

product = db.relationship("Product", primaryjoin="ProductToRelated.skuid=Product.skuid")
related_product = db.relationship("Product", primaryjoin="ProductToRelated.related_skuid=Product.skuid")

您在这里创建的是使用ProductToRelated作为关联表的产品与自身之间的自参考多对多关系。最好按照sqlalchemy文档中的https://docs.sqlalchemy.org/en/13/orm/join_conditions.html#self-referential-many-to-many-relationship进行建模,而不是使用两个单独的映射类来描述同一对象。