我试图从数据库(Python,Postgres)中获取结果集中字段的表名。PHP中有一个函数用于获取字段的表名,我使用了它,它可以工作,所以我知道它可以完成(在PHP中)。我在Python中寻找类似的函数。
PHP中的pg_field_table()函数获取结果和字段号,并“返回该字段所属的表的名称”。这正是我需要的,但在Python中。
简单示例-创建表、插入行、选择数据:

CREATE TABLE table_a (
    id INT,
    name VARCHAR(10)
);

CREATE TABLE table_b (
    id INT,
    name VARCHAR(10)
);

INSERT INTO table_a (id, name) VALUES (1, 'hello');
INSERT INTO table_b (id, name) VALUES (1, 'world');

当使用psycopg2sqlalchemy时,我得到了正确的数据和字段名,但没有表名的信息。
import psycopg2

query = '''
    SELECT *
    FROM table_a A
    LEFT JOIN table_b B
        ON A.id = B.id
'''

con = psycopg2.connect('dbname=testdb user=postgres password=postgres')
cur = con.cursor()
cur.execute(query)

data = cur.fetchall()
print('fields', [desc[0] for desc in cur.description])
print('data', data)

上面的示例打印字段名。输出为:
fields ['id', 'name', 'id', 'name']
data [(1, 'hello', 1, 'world')]

我知道有cursor.description,但它不包含表名,只包含字段名。
我需要的是-当使用原始SQL查询数据时,用某种方法检索结果集中字段的表名。
编辑1:我需要知道“hello”是来自“table_a”还是“table_ab”,这两个字段的名称都是相同的(“name”)。如果没有表名的信息,就无法判断值在哪个表中。
编辑2:我知道有一些解决方法,比如SQL别名:SELECT table_a.name AS name1, table_b.name AS name2,但我确实在问如何从结果集中检索表名。
编辑3:我正在寻找一种解决方案,它允许我编写任何原始的SQL查询,有时SELECT *,有时SELECT A.id, B.id ...,执行该查询后,我将获得结果集中字段的字段名和表名。

最佳答案

有必要查询pg_attribute catalog中的表限定列名:

query = '''
    select
        string_agg(format(
            '%%1$s.%%2$s as "%%1$s.%%2$s"',
            attrelid::regclass, attname
        ) , ', ')
    from pg_attribute
    where attrelid = any (%s::regclass[]) and attnum > 0 and not attisdropped
'''

cursor.execute(query, ([t for t in ('a','b')],))
select_list = cursor.fetchone()[0]

query = '''
    select {}
    from a left join b on a.id = b.id
'''.format(select_list)

print cursor.mogrify(query)
cursor.execute(query)
print [desc[0] for desc in cursor.description]

输出:
    select a.id as "a.id", a.name as "a.name", b.id as "b.id", b.name as "b.name"
    from a left join b on a.id = b.id

['a.id', 'a.name', 'b.id', 'b.name']

10-06 14:22
查看更多