postgresql 使用SQLAlchemy在select语句中生成带有子查询的SQL作为列

ws51t4hk  于 5个月前  发布在  PostgreSQL
关注(0)|答案(3)|浏览(63)

有没有一种方法可以让SQLAlchemy生成一个带有自定义列的查询,该自定义列是一个与当前行相关的子查询:

SELECT
 tab1.id,
 tab1.col1, 
 ...,
 (
     SELECT count(1) FROM tab2 
     WHERE tab2.tab1_id = tab1.id
     GROUP BY tab2.col1
 ) as cnt
FROM tab1
WHERE ...
LIMIT 100

字符串
使用ORM API?

session.query(Tab1, ?(subquery for additional column)?).filter(...).limit(100)


我使用PostgreSQL 9.3和旧版本的SQLAlchemy 0.9.8

fkaflof6

fkaflof61#

如果你经常需要这个属性,并且/或者count是Tab1模型的一个组成部分,你应该使用一个混合属性,比如在另一个答案中描述的。另一方面,如果你只需要一个查询,那么你可以使用Query.label()Query.as_scalar()创建标量子查询:

count_stmt = session.query(func.count(1)).\
    filter(Tab2.tab1_id == Tab1.id).\
    group_by(Tab2.col1).\
    label('cnt')

session.query(Tab1, count_stmt).filter(...).limit(100)

字符串
子查询将自动关联它可以从封闭查询中得到的内容。

vd8tlhqk

vd8tlhqk2#

你可以这样做,但是它的工作方式与你写的完全不同。你可以创建一个Tab1的属性,它取决于与tab2的关系(假设tab2.tab1_id是一个外键,它应该是。
你的模型看起来像这样:

class Parent(Base):
    __tablename__ = 'parent'
    id = Column(Integer, primary_key=True)
    children = relationship("Child")

class Child(Base):
    __tablename__ = 'child'
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey('parent.id'))

字符串
根据the docs on relationships
然后,您可以添加类似于

@hybrid_property
def number_of_children(self):
    if self.children:
        return len(self.children)
    return 0

@number_of_children.expression
def number_of_children(cls):
    return (select([func.count(Child.id)])
            .where(Child.cover_id == cls.id))


到父模型,根据this answer和更多文档。
完成此操作后,可以像过滤其他基于列的属性一样过滤此属性。

7tofc5zh

7tofc5zh3#

SQLAlchemy 2用户

只需为子查询语句定义一个select语句,然后就可以将其用作另一个select语句中的列。
以Ilja Everilä为例:

count_stmt = (select(func.count(1))
              .where(Tab2.tab1_id == Tab1.id)
              .group_by(Tab2.col1)
              .scalar_subquery()
              .label('cnt'))

字符串
更多的细节在SQLAlchemy 2.0文档中。

相关问题