栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

SQLAlchemy,array_agg和匹配输入列表

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SQLAlchemy,array_agg和匹配输入列表

我认为您的解决方案将产生不确定的结果,因为组中的行处于未指定的顺序,因此基于此,数组聚合和给定数组之间的比较可能会产生true或false:

[local]:5432 u@sopython*=> select group_id[local] u@sopython- > from multi_groups [local] u@sopython- > group by group_id[local] u@sopython- > having array_agg((atom_id, sequence)) = ARRAY[(1,3),(2,2),(3,1)]; group_id ----------        2(1 row)[local]:5432 u@sopython*=> update multi_groups set atom_id = atom_id where atom_id = 2;UPDATE 2[local]:5432 u@sopython*=> select group_id from multi_groups group by group_idhaving array_agg((atom_id, sequence)) = ARRAY[(1,3),(2,2),(3,1)]; group_id ----------(0 rows)

您可以对两者都应用排序,也可以尝试完全不同的方法:可以使用关系除法来代替数组比较。

为了进行划分,您必须从

Entity
记录列表中形成一个临时关系。同样,有很多方法可以解决这个问题。这是一个使用非嵌套数组的数组:

In [112]: vtm = select([     ...:     func.unnest(postgresql.array([     ...:         getattr(e, f) for e in values_to_match     ...:     ])).label(f)     ...:     for f in Entity._fields     ...: ]).alias()

另一个使用联合:

In [114]: vtm = union_all(*[     ...:     select([literal(e.atom_id).label('atom_id'),     ...:  literal(e.sequence).label('sequence')])     ...:     for e in values_to_match     ...: ]).alias()

临时表也可以。

有了新的关系,您想找到答案“找到那些

multi_groups
不存在的不在组中的实体”。这句话很可怕,但是很有意义:

In [117]: mg = aliased(MultiColumnGroups)In [119]: session.query(MultiColumnGroups.group_id).     ...:     filter(~exists().     ...:         select_from(vtm).     ...:         where(~exists().     ...:  where(MultiColumnGroups.group_id == mg.group_id).     ...:  where(tuple_(vtm.c.atom_id, vtm.c.sequence) ==     ...:        tuple_(mg.atom_id, mg.sequence)).     ...:  correlate_except(mg))).     ...:     distinct().     ...:     all()     ...: Out[119]: [(2)]

另一方面,您也可以选择与给定实体的组的交集:

In [19]: gs = intersect(*[    ...:     session.query(MultiColumnGroups.group_id).    ...:         filter(MultiColumnGroups.atom_id == vtm.atom_id,    ...:     MultiColumnGroups.sequence == vtm.sequence)    ...:     for vtm in values_to_match    ...: ])In [20]: session.execute(gs).fetchall()Out[20]: [(2,)]

错误

ProgrammingError: (psycopg2.ProgrammingError) operator does not exist: record[] = integer[]LINE 3: ...gg((multi_groups.atom_id, multi_groups.sequence)) = ARRAY[AR...      ^HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts. [SQL: 'SELECt multi_groups.group_id AS multi_groups_group_id nFROM multi_groups GROUP BY multi_groups.group_id nHAVINg array_agg((multi_groups.atom_id, multi_groups.sequence)) = %(array_agg_1)s'] [parameters: {'array_agg_1': [[1, 3], [2, 2], [3, 1]]}] (Background on this error at: http://sqlalche.me/e/f405)

是您如何

values_to_match
首先将DB-
API驱动程序转换为
列表(由于未知原因)然后将其转换为数组的结果。结果是一个整数数组的数组,而不是一个记录数组(int,int)。使用原始的DB-
API连接
和游标,传递元组列表可以按预期工作。

在SQLAlchemy的,如果你包裹清单

values_to_match
sqlalchemy.dialects.postgresql.array()
,它可以作为你的意思是它的工作,但请记住,结果是不确定的。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/640545.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号