SQLAlchemy外键映射到ID列表,而不是实体

SQLAlchemy外键映射到ID列表,而不是实体,sqlalchemy,Sqlalchemy,在通常的CustomerwithOrders示例中,这种SQLAlchemy代码 data = db.query(Customer)\ .join(Order, Customer.id == Order.cst_id)\ .filter(Order.amount>1000) …将提供与大订单(amount>1000)相关的客户模型实例。生成的客户实例还将包括他们的订单列表,因为在本例中,我们使用了backref,原因如下: class Order: ...

在通常的
Customer
with
Order
s示例中,这种SQLAlchemy代码

data = db.query(Customer)\
    .join(Order, Customer.id == Order.cst_id)\
    .filter(Order.amount>1000)
…将提供与大订单(
amount>1000
)相关的客户模型实例。生成的客户实例还将包括他们的订单列表,因为在本例中,我们使用了
backref
,原因如下:

class Order:
    ...
    customer = relationship("customers", backref=backref('orders'))
这样做的问题是,迭代
Customer.orders
意味着数据库将返回完整的Order实例——基本上是对Order的所有列执行“select*”

如果出于性能原因,希望从订单(例如id)中仅读取1个字段,并将客户实例中的
.orders
字段作为简单的id列表,该怎么办

customers = db.query(Customer)....
...
pdb> print customers[0].orders
[2,4,7]

使用SQLAlchemy是否可能实现这一点?

您可以通过以下方式进行查询:

(
    session.query(Customer.id, Order.id)
    .select_from(Customer)
    .join(Customer.order)
    .filter(Order.amount > 1000)
)
它不会产生您所要求的确切结果,但它会提供一个元组列表,看起来像
[(customer\u id,order\u id),…]

我不完全确定您是否可以急切地将
订单ID
加载到
客户
对象中,但我认为应该加载,您可能需要查看,也许还需要浏览一下if

在这种情况下,它是有效的,你可以这样写

(
    session.query(Customer)
    .select_from(Customer)
    .join(Customer.order)
    .options(db.joinedload(Customer.orders))
    .filter(Order.amount > 1000)
)

还可以使用来避免加载其他列。

我最终以最佳方式完成了此操作—使用数组聚合:

data = db.query(Customer).with_entities(
    Customer,
    func.ARRAY_AGG(
        Order.id,
        type_=ARRAY(Integer, as_tuple=True)).label('order_ids')
    ).outerjoin(
        Orders, Customer.id == Order.cst_id
    ).group_by(
        Customer.id
    )
这将返回(CustomerEntity,list)的元组,这正是我想要的