【问题标题】:Many-to-many join table with additional field in FlaskFlask中带有附加字段的多对多连接表
【发布时间】:2020-04-21 23:12:29
【问题描述】:

我的 Flask-SqlAlchemy 设置中有两个表 ProductsOrders,它们是链接在一起的,因此一个订单可以包含多个产品:

class Products(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    ....

class Orders(db.Model):
    guid = db.Column(db.String(36), default=generate_uuid, primary_key=True)
    products = db.relationship(
        "Products", secondary=order_products_table, backref="orders")
    ....

链接方式:

order_products_table = db.Table("order_products_table",
    db.Column('orders_guid', db.String(36), db.ForeignKey('orders.guid')),
    db.Column('products_id', db.Integer, db.ForeignKey('products.id'))
    # db.Column('license', dbString(36))
)

就我而言,订单中的每个产品都会收到一个唯一的许可证字符串,逻辑上应该将其添加到订单中每个产品的order_products_table 行中。

如何在连接表order_products_table 上声明第三个license 列,以便在我插入订单时填充它?

【问题讨论】:

    标签: python flask sqlalchemy many-to-many flask-sqlalchemy


    【解决方案1】:

    我从 SQLAlchemy 文档中找到了 Association Object 的文档,它允许对连接表进行这种扩展。

    更新设置:

    # Instead of a table, provide a model for the JOIN table with additional fields 
    # and explicit keys and back_populates:
    class OrderProducts(db.Model):
        __tablename__ = 'order_products_table'
        orders_guid = db.Column(db.String(36), db.ForeignKey(
            'orders.guid'), primary_key=True)
        products_id = db.Column(db.Integer, db.ForeignKey(
            'products.id'), primary_key=True)
    
        order = db.relationship("Orders", back_populates="products")
        products = db.relationship("Products", back_populates="order")
    
        licenses = db.Column(db.String(36), nullable=False)
    
    class Products(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        order = db.relationship(OrderProducts, back_populates="order")
        ....
    
    class Orders(db.Model):
        guid = db.Column(db.String(36), default=generate_uuid, primary_key=True)
        products = db.relationship(OrderProducts, back_populates="products")
        ....
    

    真正棘手的(但也显示在文档页面上)是如何插入数据。就我而言,它是这样的:

    o = Orders(...) # insert other data
    for id in products:
        # Create OrderProducts join rows with the extra data, e.g. licenses
        join = OrderProducts(licenses="Foo")
        # To the JOIN add the products 
        join.products = Products.query.get(id)
        # Add the populated JOIN as the Order products
        o.products.append(join)
    
    # Finally commit to database
    db.session.add(o)
    db.session.commit()
    

    我最初尝试直接填充 Order.products(或示例代码中的 o.products),当它需要 OrderProducts 类时,这会给您一个关于使用 Products 类的错误。

    我还为back_populates 的整个字段命名和引用而苦恼。同样,上面和文档中的示例显示了这一点。请注意,复数完全与您希望字段命名的方式有关。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-13
      • 1970-01-01
      • 1970-01-01
      • 2015-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多