PostgreSQL 8 min read

PostgreSQLでテーブル一覧を表示する ― \dtとpg_tables・information_schema

PostgreSQL には MySQL の SHOW TABLES に当たる SQL がありません。psql のメタコマンド \dt を使うか、カタログを SELECT します。この記事の出力は PostgreSQL 17.6 で採りました。例のデータベースには、public スキーマに表 customers とビュー v_orders、app スキーマに表 orders があります。

まず見る(結論)

  • psql なら \dt。ただし出るのは search_path にあるスキーマの表だけ
  • 全スキーマの表を見るなら \dt *.* か、スキーマを指定して \dt app.*
  • SQL で取るなら pg_tables(表だけ)か information_schema.tables(ビューも含む)

\dt で表示する

\dt
           List of relations
 Schema |   Name    | Type  |  Owner
--------+-----------+-------+----------
 public | customers | table | postgres
(1 row)

app スキーマの orders は出ていません。\dt は search_path(既定は "$user", public)にあるスキーマしか見ないためです。ほかのスキーマはパターンで指定します。

\dt app.*
         List of relations
 Schema |  Name  | Type  |  Owner
--------+--------+-------+----------
 app    | orders | table | postgres
(1 row)

\dt *.* にすると全スキーマが対象になります。ただし pg_catalog と information_schema のシステム表も並ぶので、自分の表を探すには向きません。

search_path にスキーマを足すと、\dt だけで両方出ます。

SET search_path TO public, app;
\dt
           List of relations
 Schema |   Name    | Type  |  Owner
--------+-----------+-------+----------
 app    | orders    | table | postgres
 public | customers | table | postgres
(2 rows)

存在しないスキーマを指定したときは、エラーにはならず次のメッセージが出ます。

\dt nosuch.*
Did not find any relation named "nosuch.*".

サイズやビューも見る

\dt+ にすると、サイズと説明(コメント)の列が増えます。

\dt+
                                     List of relations
 Schema |   Name    | Type  |  Owner   | Persistence | Access method | Size  | Description
--------+-----------+-------+----------+-------------+---------------+-------+-------------
 public | customers | table | postgres | permanent   | heap          | 16 kB |
(1 row)

ビューは \dv、表・ビュー・シーケンスなどをまとめて見るなら引数なしの \d です。

\d
           List of relations
 Schema |   Name    | Type  |  Owner
--------+-----------+-------+----------
 public | customers | table | postgres
 public | v_orders  | view  | postgres
(2 rows)

SQL で一覧を取る

アプリケーションやスクリプトから取るときは SQL を使います。システムのスキーマを除外して、search_path に関係なく全スキーマの表を出せます。

SELECT schemaname, tablename
  FROM pg_tables
 WHERE schemaname NOT IN ('pg_catalog', 'information_schema');
 schemaname | tablename
------------+-----------
 public     | customers
 app        | orders
(2 rows)

pg_tables は表だけです。ビューも含めたいときは SQL 標準の information_schema.tables を使い、table_type で区別します。

SELECT table_schema, table_name, table_type
  FROM information_schema.tables
 WHERE table_schema NOT IN ('pg_catalog', 'information_schema')
 ORDER BY 1, 2;
 table_schema | table_name | table_type
--------------+------------+------------
 app          | orders     | BASE TABLE
 public       | customers  | BASE TABLE
 public       | v_orders   | VIEW
(3 rows)

information_schema は、そのユーザーが何らかの権限を持つ表だけを返します。権限の無い表まで含めて調べるなら pg_tables を使います。

表が出てこないとき

  • 別のスキーマにある: \dt *.表名 でスキーマを探す
  • 別のデータベースにつないでいる: SELECT current_database(); で確かめ、\c データベース名 で切り替える
  • 大文字を含む名前で作った: \dt "Users" のように二重引用符で囲む

表はあるのに SELECT すると relation does not exist になる場合は、PostgreSQLの「relation does not exist」で原因ごとの確かめ方をまとめています。

データベースの一覧は \l で出せます。表の列や型を見るなら \d 表名 です。