繁体   English   中英

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

[英]PostgreSQL - query all tables' all table columns

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

我试过的方法:

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

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

有没有优雅的方法来做到这一点?

由于您使用的是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])]

您可以使用array_agg()并在information_schema.tablesinformation_schema.columns表上进行array_agg()在单个查询中执行此操作。

这将返回类似于您的预期输出的内容:

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()将它们全部聚集到按表名分组的数组中。

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

它是指定模式中所有表查询

SELECT 
    pg_namespace.nspname as schema_name,
    relname as table_name,
    pg_catalog.obj_description(pg_class.oid) as comment
    FROM pg_class
    INNER JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
    WHERE pg_namespace.nspname IN ('public') AND pg_class.relkind IN ('r', 't')
    ORDER BY relname

该示例仅过滤public架构,但您可以指定自己的架构。
Condition relkind IN ('r', 't')描述我们只需要表,不需要索引、序列等。
这是表 pg_class 的文档 - https://www.postgresql.org/docs/current/catalog-pg-class.html函数pg_catalog.obj_description返回数据库对象的注释。 这是一个文档: https : //www.postgresql.org/docs/current/functions-info.html#FUNCTIONS-INFO-COMMENT-TABLE

它作为指定表中所有列的查询

SELECT 
    attrelid::regclass AS table_name,
    attname            AS column_name, 
    pg_catalog.col_description(attrelid, attnum) as column_comment,
    atttypid::regtype  AS column_datatype
    FROM pg_attribute
    INNER JOIN pg_class ON pg_class.oid = attrelid
    WHERE attrelid IN (
        SELECT pg_class.oid
        FROM pg_class
        INNER JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
        WHERE pg_namespace.nspname IN ('public') AND pg_class.relkind IN ('r', 't')
    )
    AND attnum > 0 AND attisdropped IS FALSE
    ORDER BY pg_class.relname, pg_attribute.attnum

条件attnum > 0 AND attisdropped IS FALSE描述我们只需要可见而不是删除的列。
这是表 pg_attribute 的文档 - https://www.postgresql.org/docs/current/catalog-pg-attribute.html函数pg_catalog.col_description返回表列的注释。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM