PostgreSQLのメタコマンドを知っておこう。

# PostgreSQLのpsqlメタコマンド完全ガイド - \o、\i、\dシリーズを使いこなそう

PostgreSQLのpsqlコマンドラインツールには、バックスラッシュ（\）で始まる便利なメタコマンドが数多く用意されています。これらのコマンドを使いこなすことで、データベース操作が格段に効率的になります。
実際の業務でもDB証跡として検証資料にスクショを貼り付けるだけでなく、クエリ結果を.txtなどで要求される可能性があるので下記を参考にして指摘を減らしましょう。

今回は、特に実用的な `\o`、`\i`、`\d` シリーズなどのメタコマンドについて、実例とともに詳しく解説します。

## psqlメタコマンドとは

psqlメタコマンドは、SQLクエリではなく、psql自体の機能を制御するコマンドです。すべて `\` で始まり、psqlプロンプト内でそのまま実行できます。（'￥'でも同じ意味）

```bash
# psqlに接続
psql -U username -d database_name

# psqlプロンプト内でメタコマンドを実行
postgres=# \l
```

## 主要なメタコマンド一覧

### 1. 出力制御系コマンド

#### `\o` - 出力先の指定

`\o` コマンドを使って、クエリ結果をファイルに出力できます。

```sql
-- ファイルに出力を開始
\o /tmp/query_result.txt

-- クエリを実行（結果がファイルに保存される）
SELECT * FROM users LIMIT 10;

-- 標準出力に戻す
\o
```

実際の使用例：
```sql
-- CSVファイルとして出力
\o /home/user/user_data.csv
\copy (SELECT name, email FROM users) TO STDOUT WITH CSV HEADER;
\o
```

#### `\t` - テーブルのヘッダー表示切り替え

```sql
-- ヘッダーを非表示にする
\t

SELECT id, name FROM users LIMIT 3;
-- 結果にはカラム名が表示されない

-- ヘッダーを再表示する
\t
```

### 2. ファイル操作系コマンド

#### `\i` - SQLファイルの実行

外部のSQLファイルを読み込んで実行できます。

```sql
-- SQLファイルを実行
\i /path/to/script.sql

-- 相対パスも使用可能
\i ./setup.sql
```

実用例：
```sql
-- setup.sql の内容
CREATE TABLE IF NOT EXISTS logs (
    id SERIAL PRIMARY KEY,
    message TEXT,
    created_at TIMESTAMP DEFAULT NOW()
);

INSERT INTO logs (message) VALUES ('System started');
```

```sql
-- psql内で実行
\i setup.sql
```

#### `\ir` - 相対パスでSQLファイルを実行

現在のファイルからの相対パスでファイルを読み込みます。

```sql
\ir ../migrations/001_create_tables.sql
```

### 3. データベース情報表示系コマンド（\dシリーズ）

#### `\l` - データベース一覧

```sql
\l
-- または
\list
```

#### `\d` - テーブル、ビュー、シーケンス一覧

```sql
-- すべてのテーブル等を表示
\d

-- 特定のテーブルの構造を表示
\d table_name

-- パターンマッチで表示
\d user*
```

#### `\dt` - テーブル一覧のみ

```sql
-- テーブルのみ表示
\dt

-- スキーマを指定
\dt public.*

-- 詳細情報付き
\dt+
```

#### `\dv` - ビュー一覧

```sql
-- ビューのみ表示
\dv

-- 詳細情報付き
\dv+
```

#### `\di` - インデックス一覧

```sql
-- インデックス一覧
\di

-- 特定のテーブルのインデックス
\di table_name
```

#### `\df` - 関数一覧

```sql
-- 関数一覧
\df

-- パターンマッチで検索
\df *user*
```

#### `\du` - ユーザー（ロール）一覧

```sql
-- ユーザー一覧
\du

-- 詳細情報付き
\du+
```

### 4. スキーマ・権限表示系コマンド

#### `\dn` - スキーマ一覧

```sql
-- スキーマ一覧
\dn

-- 詳細情報付き
\dn+
```

#### `\dp` または `\z` - テーブルの権限表示

```sql
-- テーブルの権限を表示
\dp table_name

-- すべてのテーブルの権限
\z
```

### 5. その他の便利なコマンド

#### `\c` - データベース接続の変更

```sql
-- 別のデータベースに接続
\c other_database

-- 別のユーザーで接続
\c database_name username
```

#### `\q` - psqlの終了

```sql
\q
```

#### `\timing` - クエリ実行時間の表示切り替え

```sql
-- 実行時間の表示をON
\timing

SELECT count(*) FROM large_table;
-- Time: 1234.567 ms と表示される

-- 実行時間の表示をOFF
\timing
```

#### `\x` - 拡張表示モード

カラム数が多いテーブルで見やすく表示できます。

```sql
-- 拡張表示モードON
\x

SELECT * FROM users WHERE id = 1;
-- 縦に表示される

-- 拡張表示モードOFF
\x
```

#### `\e` - エディタでクエリを編集

```sql
-- デフォルトエディタでクエリを編集
\e

-- ファイルを指定してエディタで開く
\e /path/to/query.sql
```

#### `\h` - SQLコマンドのヘルプ

```sql
-- SELECT文のヘルプ
\h SELECT

-- CREATE TABLEのヘルプ
\h CREATE TABLE
```

#### `\?` - psqlコマンドのヘルプ

```sql
-- すべてのメタコマンドの一覧とヘルプ
\?
```

## 実践的な使用例

### ログ出力とバックアップ作成

```sql
-- クエリ結果をファイルに出力
\o /tmp/user_report.txt
\t
SELECT 'User Report - ' || current_date;
SELECT '=====================================';
SELECT count(*) || ' total users' FROM users;
SELECT '=====================================';
\t
\o

-- バックアップ用のINSERT文を生成
\o /tmp/users_backup.sql
SELECT 'INSERT INTO users (name, email) VALUES (''' || name || ''', ''' || email || ''');'
FROM users;
\o
```

### データベース調査の効率化

```sql
-- データベース全体の構造を把握
\l                    -- データベース一覧
\c target_database    -- 対象DBに接続
\dn                   -- スキーマ確認
\dt                   -- テーブル一覧
\d+ users            -- 特定テーブルの詳細
\di users            -- インデックス確認
\dp users            -- 権限確認
```

### 開発環境のセットアップ

```sql
-- 初期化スクリプトの実行
\i create_database.sql
\i create_tables.sql
\i insert_sample_data.sql
\i create_indexes.sql

-- 結果の確認
\dt+
SELECT 'Setup completed at ' || current_timestamp;
```

## Tips & 注意点

### エラーハンドリング

```sql
-- エラー時にスクリプト実行を停止
\set ON_ERROR_STOP on

\i potentially_failing_script.sql
```

### 変数の使用

```sql
-- 変数を設定
\set table_name 'users'

-- 変数を使用（シングルクォート内では展開されない）
SELECT * FROM :table_name;
```

### パスワードプロンプトの制御

```sql
-- パスワードプロンプトを非表示
\set QUIET on
\c database_name username
\set QUIET off
```

## まとめ

psqlのメタコマンドを活用することで、以下のようなメリットがあります：

- **効率的なデータベース調査**: `\d` シリーズでスキーマ情報を素早く把握
- **結果の永続化**: `\o` でクエリ結果をファイルに保存
- **スクリプト化**: `\i` で複雑な処理を自動化
- **開発効率の向上**: 各種表示オプションで見やすい出力

これらのコマンドを組み合わせることで、PostgreSQLでの作業が格段に効率的になります。ぜひ日常の開発業務で活用してみてください！

## 参考

- [PostgreSQL 公式ドキュメント - psql](https://www.postgresql.org/docs/current/app-psql.html)
- より詳細な情報については `\?` コマンドでpsql内からヘルプを確認できます