SQLAlchemy,子查询和实体

时间:2015-04-03 07:05:45

标签: sql sqlalchemy

我有一个返回(Document,list_of_document_tag_ids)元组的查询。它通过Document.id分组,并在整数的ARRAY中聚合关联的标签:

data_with_tags = data.with_entities(
    Document,
    func.ARRAY_AGG(
        DocumentTag.tag_id,
        type_=ARRAY(Integer, as_tuple=True)).label('tags')
    ).outerjoin(
        DocumentTag, Document.id == DocumentTag.document_id
    ).group_by(
        Document.id
    )

这很好用而且非常快 - 它还返回类型为(Document, list)的元组。

现在,我想通过一个字段对结果元组(Document, tagid_list)进行排序......两个表格:-)每个文档引用一个库,每个库引用一个市政 - 好吧,我应该通过相关的市政名称订购元组。

我天真地试图这样做,首先:

data_with_tags = data.with_entities(
    ...
    ).outerjoin(
        Library, Document.libId == Library.id
    ).outerjoin(
        Municipality, Library.muniId == Municipality.id
    ).order_by(Municipality.name)

(注意:如果您想知道,我使用了.outerjoin(即SQL中的LEFT JOIN),因为文档数据可能指向现在已删除的库和/或城市 - 我们不知道t希望生成的元组列表删除这些文档。)

不幸的是,这不起作用 - SQLAlchemy认为这一切都很好,但Postgres回答说......

ProgrammingError: (ProgrammingError) column "municipality.name" 
must appear in the GROUP BY clause or be used in an aggregate function

换句话说,它希望我将Municipality.name添加到group_by子句中。

为什么会这样做?

当我尝试按文档中的任何字段进行排序时似乎没有发生 - 例如:

data_with_tags = data.with_entities(
    Document,
    func.ARRAY_AGG(
        DocumentTag.tag_id,
        type_=ARRAY(Integer, as_tuple=True)).label('tags')
    ).outerjoin(
        DocumentTag, Document.id == DocumentTag.document_id
    ).group_by(
        Document.id
    ).order_by(
        Document.author
    )

因此有时候order_by中使用的字段需要出现在group_by中,有时则不出现。

P.S。注意,在将ordericipality.name添加到order_by之后,一切似乎都运行正常......我只是好奇为什么order_by字段有时需要出现在group_by中 - 但并非总是如此。

0 个答案:

没有答案