PostgreSQL-查询所有表的所有表列

时间:2018-08-21 03:25:12

标签: python sql arrays database postgresql

如何查询数据库中所有表的所有表列?

我尝试过的方法:

  1. 使用select tablename from pg_tables where schemaname = 'public'
  2. 获取所有表名
  3. 使用Postgres的UNION方法处理cmd字符串。
  4. 执行cmd字符串。

我在一个数据库中有19个表,而我的方法导致查询时间慢19倍。而且,它不会返回我想要的东西。所有表都有两列,其中之一始终是名为time的列名。使用UNION方法不会返回19个time字符串。它仅返回一个time字符串和其他19个列名称。但是我想要这样的东西: [('table_1', ['time', 'col']), ('table_2', ['time', 'col']), ('table_3', ['time', 'col])...]

有什么优雅的方法吗?

2 个答案:

答案 0 :(得分:2)

由于您使用的是Python,因此我认为如果分两个步骤进行处理,这是最清楚的。首先,使用此查询来检索表/列名称对:

select table_name, column_name 
from information_schema.columns 
where table_name in (
    select tablename from pg_tables where schemaname = 'public');

然后,将结果粘贴到defaultdict中:

from collections import defaultdict

my_cols = <your code to execute the query above and fetch all rows>
column_mapping = defaultdict(list)
for tablename, colname in my_cols:
    column_mapping[tablename].append(colname)

这将为您提供:

>>> column_mapping
defaultdict(<type 'list'>, {'table_1': ['time', 'col'], 'table_2': ['time', 'col'], 'table_3': ['time', 'col]})

您可以使用以下方法进行简单转换:

>>> column_mapping.items()
[('table_1', ['time', 'col']), ('table_2', ['time', 'col']), ('table_3', ['time', 'col])]

答案 1 :(得分:2)

您可以使用array_agg()并在information_schema.tablesinformation_schema.columns表上进行联接,从而在单个查询中完成此操作。

这将返回与您期望的输出相似的东西:

select
    t.table_name,
    array_agg(c.column_name::text) as columns
from
    information_schema.tables t
inner join information_schema.columns c on
    t.table_name = c.table_name
where
    t.table_schema = 'public'
    and t.table_type= 'BASE TABLE'
    and c.table_schema = 'public'
group by t.table_name;

在这里,我先获取所有表,然后将其与列表合并,最后使用array_agg()将它们全部聚集到一个按表名分组的数组中。

希望它会有所帮助:)随时询问您是否有任何疑问。