2

我正在使用 Flask-SQLAlchemy 在 Flask 中工作,并尝试建立多对多对多的关系:客户可以有多个订单,订单也可以有多个客户(多对多);每个订单又包含一个独特项目的列表(一对多)。

我按照 SQLAlchemy 文档为多对多关系设置关联表,并为一对多关系使用普通关系/外键;所有引用都设置为lazy='dynamic'.

association_table = Table('association', Base.metadata,
Column('left_id', Integer, ForeignKey('left.id')),
Column('right_id', Integer, ForeignKey('right.id'))
)

items检索与客户相关的所有内容的有效方法是什么?我假设[item for item in order.items.all() for order in client.orders]会起作用(少了上面的问题),但是有没有更有效的方法呢?如果需要订购结果怎么办?


更新

我现在知道通过以下两种方法(第一种来自 Audrius 的回答)来检索客户订单的项目的两种方法:

db.session.query(Item).\
    join(Order).join(Order.clients).\
    filter(Client.id == 42).\
    order_by(Item.timestamp)

Item.query.filter(Item.order_id._in(client.order_ids)).order_by(Item.timestamp)‌​

我相信它们都提供了相同的结果,但是为了提高效率应该首选哪一个?

4

1 回答 1

1

当直接在 SQL 中编写查询时,您将使用连接来有效地检索您想要的数据(正如 Rachcha 在他的回答中所展示的那样)。这同样适用于 SQLAlchemy。join()有关更多示例,请参阅 SA 文档。

如果您的模型定义如下(使用 Flask-SQLAlchemy,因为您使用其标签标记了您的问题):

clients_orders = db.Table('clients_orders',
    db.Column('client_id', db.Integer, db.ForeignKey('client.id'),
              primary_key=True),
    db.Column('order_id', db.Integer, db.ForeignKey('order.id'),
              primary_key=True)
)

class Client(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    orders = db.relationship('Order', secondary=clients_orders,
                             backref='clients')
    # Define other columns...

class Order(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    # Define other columns...

class Item(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    order_id = db.Column(db.Integer, db.ForeignKey('order.id'), nullable=False)
    order = db.relationship('Order', backref='items')
    timestamp = db.Column(db.DateTime)
    # Define other columns...

然后您的查询可能如下所示:

db.session.query(Item).\
    join(Order).join(Order.clients).\
    filter(Client.id == 42).\
    order_by(Item.timestamp)
于 2013-03-17T14:29:03.530 回答