SQLAlchemy:在三个表的union_all子查询中列名加前缀

8 投票
1 回答
2589 浏览
提问于 2025-04-27 22:48

这是我的mssql代码片段

cnt = func.count(pvr_svc.ic_idn).label('cnt')

x = session.query(pvr_svc.inc_type_md, cnt, cast(pvr_svc.crt_dt,DATE)
         .label('crt_dt'))
         .filter(pvr_svc.inc_type_md.in_(['PM','OM','OP-HU']))
         .group_by(cast(pvr_svc.crt_dt, DATE), pvr_svc.inc_type_md)

y = session.query(pvr_svc.inc_type_md, cnt, cast(pvr_svc.crt_dt,DATE)
         .label('crt_dt'))
         .filter(pvr_svc.gold_idn==2)
         .group_by(cast(pvr_svc.crt_dt, DATE), pvr_svc.inc_type_md)

我想做的是

from sqlalchemy import union_all

u1 = x.union_all(y)     # ----- 1

在"u1"中的列名是这样提取的

 >>>[i['name'] for i in u1.column_descriptions]  

 >>>['inc_type_md', 'cnt', 'crt_dt']   # column names

现在如果我想在未来使用'u1',我会这样做

>>>v1 = u1.subquery()    #------ 2

要访问"v1"中的列名,我这样做

>>>v1.c.keys()

>>>[u'pvr_svc_inc_type_md', u'cnt', u'crt_dt']

现在,如果你看看'u1'和'v1'中的第一个键('v1'是'u1'的子查询),它们是不同的。我希望它们是一样的。

为了避免这个问题,我会给"x"和"y"查询中的列名加上标签

x = session.query(pvr_svc.inc_type_md.label('inc_type_md'), cnt, cast(pvr_svc.crt_dt,DATE).label('crt_dt')
         .label('crt_dt'))
         .filter(pvr_svc.inc_type_md.in_(['PM','OM','OP-HU']))
         .group_by(cast(pvr_svc.crt_dt, DATE), pvr_svc.inc_type_md)

y = session.query(pvr_svc.inc_type_md.label('inc_type_md'), cnt, cast(pvr_svc.crt_dt,DATE).label('crt_dt')
         .label('crt_dt'))
         .filter(pvr_svc.gold_idn==2)
         .group_by(cast(pvr_svc.crt_dt, DATE), pvr_svc.inc_type_md)

然后重复步骤1和2,这样就可以正常工作了。

现在我的问题是

我想把"u1"和第三个查询"z"做一个union_all,我已经给"z"中的列名加上了标签

z = session.query(pvr_svc.inc_type_md.label('inc_type_md'), cnt, cast(pvr_svc.crt_dt,DATE).label('crt_dt')
         .label('crt_dt'))
         .filter(pvr_svc.gold_idn==4)
         .group_by(cast(pvr_svc.crt_dt, DATE), pvr_svc.inc_type_md)

我会这样做来将三个查询合并

>>>union_xyz = u1.union_all(z)

现在我想在未来的查询中使用"union_xyz",所以我从中创建一个子查询

>>>sub_xyz = union_xyz.subquery()

现在的问题是,sub_xyz中的列名前面加了一些数字

所以,我得到的是这个,

>>>sub_xyz.c.keys()
>>>[u'%(2911061292 anon)s_inc_type_md', u'%(2911061292 anon)s_cnt', u'%(2911061292 anon)s_crt_dt']

如何避免列名前面的数字?

我查看了sqlalchemy文档

我发现了一个类似的问题在 如何防止sqlalchemy给CTE的列名加前缀?

暂无标签

1 个回答

4

我不知道有什么方法可以阻止前缀的添加,但你可以把子查询中的 c 属性转换成一个列表或元组,然后通过位置来访问各个列。这里有一个使用元组解包的例子:

>>> inc_type_md_col, cnt_col, ctr_dt_col = tuple(subq_xyz.c)

inc_type_md_colcnt_colctr_dt_col 现在都是有效的列对象,你可以对它们做任何你想做的事情,比如:

>>> session.query(inc_type_md_col).filter(cnt_col > 0)

撰写回答