gpt4 book ai didi

python - 如何防止 sqlalchemy 在 CTE 的列名前添加前缀?

转载 作者:太空宇宙 更新时间:2023-11-03 19:03:28 25 4
gpt4 key购买 nike

考虑以下通过 SQLAlchemy 编码的查询。

# Create a CTE that performs a join and gets some values
x_cte = session.query(SomeTable.col1
,OtherTable.col5
) \
.select_from(SomeTable) \
.join(OtherTable, SomeTable.col2 == OtherTable.col3)
.filter(OtherTable.col6 == 34)
.cte(name='x')

# Create a subquery that splits the CTE based on the value of col1
# and computes the quartile for positive col1 and assigns a dummy
# "quartile" for negative and zero col1
subquery = session.query(x_cte
,literal('-1', sqlalchemy.INTEGER).label('quartile')
) \
.filter(x_cte.col1 <= 0)
.union_all(session.query(x_cte
,sqlalchemy.func.ntile(4).over(order_by=x_cte.col1).label('quartile')
)
.filter(x_cte.col1 > 0)
) \
.subquery()

# Compute some aggregate values for each quartile
result = session.query(sqlalchemy.func.avg(subquery.columns.x_col1)
,sqlalchemy.func.avg(subquery.columns.x_col5)
,subquery.columns.x_quartile
) \
.group_by(subquery.columns.x_quartile) \
.all()

抱歉,篇幅较长,但这与我的真实查询类似。在我的真实代码中,我为我的 CTE 指定了一个更具描述性的名称,并且我的 CTE 有更多的列,我必须计算平均值。 (它实际上也是按 CTE 中的列加权的加权平均值。)

真正的“问题”纯粹是试图让我的代码更清晰、更短。 (是的,我知道。这个查询已经是一个怪物并且难以阅读,但是客户端坚持要求这些数据可用。)请注意,在最终查询中,我必须将我的列引用为 subquery.columns.x_ [列名称];这是因为 SQLAlchemy 在我的列名前面加上了 CTE 名称作为前缀。我只是希望 SQLAlchemy 在生成列名称时省略我的 CTE 名称,但由于我有很多列,所以我不想在子查询中单独列出它们。省略 CTE 名称将使我的列名称(它们本身就足够长)更短且更具可读性;我可以保证这些列是唯一的。我怎样才能做到这一点?

使用 Python 2.7.3 和 SQLAlchemy 0.7.10。

最佳答案

您并没有太具体地说明“x_”在这里,但如果这是最终结果,请使用 label() 为结果列提供您想要的任何名称:

row = session.query(func.avg(foo).label('foo_avg'), func.avg(bar).label('bar_avg')).first()
foo_avg = row['foo_avg'] # indexed access
bar_avg = row.bar_avg # attribute access

编辑:我无法在此处重现“x_”。这是一个测试:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class A(Base):
__tablename__ = "a"

id = Column(Integer, primary_key=True)

x = Column(Integer)
y = Column(Integer)

s = Session()

subq = s.query(A).cte(name='x')

subq2 = s.query(subq, (subq.c.x + subq.c.y)).filter(A.x == subq.c.x).subquery()

print s.query(A).join(subq2, A.id == subq2.c.id).\
filter(subq2.c.x == A.x, subq2.c.y == A.y)

上面你可以看到我可以引用subq2.c.<colname>没有问题,前面没有“x”。如果您可以指定 SQLAlchemy 版本信息并完整填写您的示例,我可以按原样运行它以重现您的问题。

关于python - 如何防止 sqlalchemy 在 CTE 的列名前添加前缀?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15416389/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com