我有一个查询,我已经建立,目标是从标签找到相关的实体(创建一个搜索栏,将提出实体)。我不想硬编码它,所以我的函数接受一个数组[“partition”,“biography”,“masterclass”]作为变量来选择搜索的位置。
下面是我的结果的一个打印的例子。它的工作,但我不满意的事实,我正在建设3个不同的查询。我想把它们重新组合成一个,以保存我的查询时间。
一开始我想使用PostgreSQL UNION ALL,但每个select语句在结果集中必须有相同数量的字段/列,这不是我能做到的。
他们会是一种更好的方式来做到这一点的方式。
我用来创建不同查询的dict:
objects = {
"biography": {
"table": biography_table,
"object_id": "biography_id",
"tag_table": biography_tag_table,
"entity": Biography,
},
"masterclass": {
"table": masterclass_table,
"object_id": "masterclass_id",
"tag_table": masterclass_tag_table,
"entity": Masterclass,
},
"partition": {
"table": partition_table,
"object_id": "partition_id",
"tag_table": partition_tag_table,
"entity": Partition,
},
}
字符串
我的职能:
cte_query = []
for table in tables:
object_table = objects[table]["table"]
object_tag_table = objects[table]["tag_table"]
object_id = objects[table]["object_id"]
cte_query.append(
sa.select(object_table, func.array_agg(tag_table.c.content).label("tags"))
.select_from(
object_table.join(
object_tag_table,
object_table.c.id == object_tag_table.c[object_id],
).join(tag_table, tag_table.c.id == object_tag_table.c.tag_id)
)
.group_by(object_table.c.id)
.cte(f"{table}_cte")
)
cte_partition, cte_biography, cte_masterclass = cte_query
print(cte_partition)
print(cte_biography)
print(cte_masterclass)
partition = sa.select(cte_partition).where(
func.lower(func.array_to_string(cte_partition.c.tags, ",")).like(
func.lower(f"%{search}%")
)
)
masterclass = sa.select(cte_masterclass).where(
func.lower(func.array_to_string(cte_masterclass.c.tags, ",")).like(
func.lower(f"%{search}%")
)
)
biography = sa.select(cte_biography).where(
func.lower(func.array_to_string(cte_biography.c.tags, ",")).like(
func.lower(f"%{search}%")
)
)
result = []
result.append(conn.execute(partition).fetchall())
result.append(conn.execute(masterclass).fetchall())
result.append(conn.execute(biography).fetchall())
print(result)
型
下面是一个结果的例子:
[[],
[(UUID('61fa9287-fd5b-49fc-8e91-037f6343b46d'), UUID('12345648-1234-1234-1234-123456789123'), 'masterclass', None, None, None, None, None, ['violon', 'flute'], 'created', datetime.datetime(2023, 7, 19, 21, 41, 55, 556527), None, UUID('12345648-1234-1234-1234-123456789123'), None, ['masterclass', 'violon', 'flute'])],
[(UUID('9bb75325-ad82-4170-908b-179e6fadd8b6'), 'flute', 'Boby', ['statement'], 'Française', 'http://www.gaines-johnson.com/', ['bag'], 'Number five region no power look. Energy government financial. Leave present nice.', 'compositor', 'created', None, datetime.datetime(2023, 7, 21, 14, 45, 19, 220057), None, UUID('12345648-1234-1234-1234-123456789123'), None, ['flute', 'boby', 'flute boby', 'statement'])]]
型
1条答案
按热度按时间htrmnn0y1#
您使用
conn.execute
运行正在构建的查询;这就是需要执行UNION
的地方。要构造它,请使用SQLAlchemy的union
函数。在这种情况下,您应该能够说
union(partition, masterclass, biography)
;如果你想让它更具可扩展性,你可以根据用户输入构建一个查询列表,并将其作为union(*queries)
传递给函数。