postgresql 组合多个PostrgreSQL查询

pgx2nnw8  于 2023-08-04  发布在  PostgreSQL
关注(0)|答案(1)|浏览(153)

我有一个查询,我已经建立,目标是从标签找到相关的实体(创建一个搜索栏,将提出实体)。我不想硬编码它,所以我的函数接受一个数组[“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'])]]

htrmnn0y

htrmnn0y1#

您使用conn.execute运行正在构建的查询;这就是需要执行UNION的地方。要构造它,请使用SQLAlchemy的union函数。
在这种情况下,您应该能够说union(partition, masterclass, biography);如果你想让它更具可扩展性,你可以根据用户输入构建一个查询列表,并将其作为union(*queries)传递给函数。

相关问题