【问题标题】:PostgreSQL - query all tables' all table columnsPostgreSQL - 查询所有表的所有表列
【发布时间】:2019-01-27 04:44:28
【问题描述】:

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

我试过的方法:

  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 sql arrays database postgresql


    【解决方案1】:

    您可以在单个查询中使用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() 将它们全部聚合到一个数组中,按表名分组。

    希望对您有所帮助 :) 如果您有任何疑问,请随时询问。

    【讨论】:

      【解决方案2】:

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

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

      然后,将结果粘贴到默认字典中:

      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])]
      

      【讨论】:

        【解决方案3】:

        这是对指定架构中所有表的查询

        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 架构,但您可以指定自己的。
        条件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 &gt; 0 AND attisdropped IS FALSE 描述我们只需要可见的列而不需要删除的列。
        这是表 pg_attribute 的文档 - https://www.postgresql.org/docs/current/catalog-pg-attribute.html 函数pg_catalog.col_description 返回表列的注释。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-01-17
          • 2020-08-04
          • 2018-02-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-21
          相关资源
          最近更新 更多