web-dev-qa-db-ja.com

テーブルのpostgresシステムカタログクエリ列

ユーザーにデータベースをプロビジョニングするアプリに対する統合テストを構築しています。そのために作成されたユーザーはスーパーユーザーではなく、次のスクリプトを実行しようとするとしないがschema_information.tablesにアクセスできます。

SELECT table_name
FROM information_schema.tables
WHERE table_schema='{schema}'

このユーザーには権限がないため、0が返されます。

データベースにクエリを実行して、作成されたテーブルと列を確認しようとしています。次のスクリプトを使用して、システムカタログからテーブル名のリストを取得できます。

SELECT tablename
FROM pg_catalog.pg_tables
WHERE schemaname = '{schema}'

そして、これは私が望む方法でテーブル名を出力します:

ビジネス、場所、人など...

システムカタログを含むスクリプトが見つからないため、各テーブルの列名(おまけとして、データ型)を見つけることができません。これまでのところ、私は以下を試しました:

SELECT attname, format_type(atttypid, atttypmod) AS type
FROM pg_attribute
WHERE  attrelid = 'business'

そしてここにエラーがあります:

ERROR:  invalid input syntax for type oid: "business"
LINE 1: ...od) AS type FROM   pg_attribute WHERE  attrelid = 'business'
                                                         ^```

また試しました:

SELECT
    a.attname as "Column",
    pg_catalog.format_type(a.atttypid, a.atttypmod) as "Datatype"
FROM
    pg_catalog.pg_attribute a
WHERE
    a.attnum > 0
    AND NOT a.attisdropped
    AND a.attrelid = (
        SELECT c.oid
        FROM pg_catalog.pg_class c
            LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
        WHERE c.relname ~ '**Dont know what to put here, Schema? Database?**'
            --AND pg_catalog.pg_table_is_visible(c.oid)
    );

スキーマまたはデータベースでは0を返します。 c.relnameに何を配置すればよいかわかりません。基本的なユーザーはスキーマ、期間内のテーブルよりも深いところしか見ることができないので、これも0と表示されますか?

4
as.beaulieu

代わりに information_schema.columns から選択してください。

SELECT table_catalog, table_schema, table_name, data_type
FROM information_schema.tables
WHERE table_schema='{schema}';

栄光のために

何らかの理由で、information_schema.columnsをクエリできない場合(それ以外の場合は、何かがファンキーであることを示します)。可能なユーザーとpsql -Eを使用すると、カタログを効率的にリバースエンジニアリングできます。次に、\のように、psqlで適切なクライアント(\d schema)コマンドを実行し、必要なものを表示します。そして、エクスポートしたクエリの必要な部分をコピーします。

私にとって、その最後の列は次のようなものです

SELECT a.attname,
  pg_catalog.format_type(a.atttypid, a.atttypmod),
  (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)
   FROM pg_catalog.pg_attrdef d
   WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef),
  a.attnotnull, a.attnum,
  (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type t
   WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation) AS attcollation,
  NULL AS indexdef,
  NULL AS attfdwoptions
FROM pg_catalog.pg_attribute a
WHERE a.attrelid = '1024334' AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum;

次に、スキーマのすべてのattrelidを取得する必要があります。クイック実行\d asdofkodskfなるほど、

SELECT c.oid,
  n.nspname,
  c.relname
FROM pg_catalog.pg_class c
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname ~ '^(asdofkodskf)$'
  AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY 2, 3;

実際にはn.nspnameではなくc.relnameが必要です

したがって、私のバージョンのpsqlを考えると、カタログを直接照会する公式の方法は...

SELECT c.oid,
  n.nspname,
  c.relname, t.*
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
CROSS JOIN LATERAL (
  SELECT a.attname,
    pg_catalog.format_type(a.atttypid, a.atttypmod),
    (
      SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)
      FROM pg_catalog.pg_attrdef d
      WHERE d.adrelid = a.attrelid
        AND d.adnum = a.attnum
        AND a.atthasdef
    ),
    a.attnotnull, a.attnum,
    (
      SELECT c.collname
      FROM
        pg_catalog.pg_collation c,
        pg_catalog.pg_type t
      WHERE c.oid = a.attcollation
        AND t.oid = a.atttypid
        AND a.attcollation <> t.typcollation
    ) AS attcollation
  FROM pg_catalog.pg_attribute a
  WHERE a.attrelid = c.oid
    AND a.attnum > 0
    AND NOT a.attisdropped
) AS t
WHERE n.nspname ~ '^(public)$'  -- YOUR SCHEMA HERE
AND pg_catalog.pg_table_is_visible(c.oid);

抜粋(すべての列またはすべての行なし)(relnameはテーブル、attnameは列)

   oid   | nspname |           relname           |       attname        |       format_type       
llation 
---------+---------+-----------------------------+----------------------+-------------------------
--------
 1024242 | public  | spatial_ref_sys_pkey        | srid                 | integer                 
 1045853 | public  | product_discount_qty_excl   | qty                  | int4range               
 1024334 | public  | valid_detail                | valid                | boolean                 
 1024334 | public  | valid_detail                | reason               | character varying       
 1024334 | public  | valid_detail                | location             | geometry                
 1045847 | public  | product_discount            | pid                  | integer                 
 1045847 | public  | product_discount            | qty                  | int4range               
 1045847 | public  | product_discount            | percent_modifier     | real                    
 1024569 | public  | geography_columns           | f_table_catalog      | name                    
2
Evan Carroll