PostgreSQLでダンプファイルからデータベースを作り直す

# ダンプファイルでデータベースを作り直す
コマンドを使ってやってみます。

```bash
# 1. 対象のデータベースを削除する
$ dropdb -e database_name -U user_name
DROP DATABASE database_name;

# 2. 削除されたことを確認する
$ psql -l -U user_name
                                             List of databases
           Name            |     Owner      | Encoding |   Collate   |    Ctype    |   Access privileges
---------------------------+----------------+----------+-------------+-------------+-----------------------
...省略...

# 3. 対象のデータベースを作成する
$ createdb -e database_name -O user_name -U user_name -T template0 --lc-collate=ja_JP.UTF-8 --lc-ctype=ja_JP.UTF-8
CREATE DATABASE database_name OWNER user_name TEMPLATE template0 LC_COLLATE 'ja_JP.UTF-8' LC_CTYPE 'ja_JP.UTF-8';

# 4. データベースが作成されたことを確認する
$ psql -l -U user_name
                                             List of databases
           Name            |     Owner      | Encoding |   Collate   |    Ctype    |   Access privileges
---------------------------+----------------+----------+-------------+-------------+-----------------------
...省略...
database_name                 | user_name   | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 |
...省略...

# 5. データベースにダンプファイルを適用する
$ psql -U user_name -d database_name < dump_file.dmp
```



```bash:createdbとdropdbのフォーマット
$ createdb [connection-option...] [option...] [dbname [description]]
$ dropdb [connection-option...] [option...] dbname
```

|オプション|意味|使えるコマンド|参考リンク|
|:--|:--|:--|:--|
|`-e`<br/>`--echo`|サーバに送信するコマンドをエコー表示する|createdb / dropdb|[dropdb - PostgreSQL 12.4文書](https://www.postgresql.jp/document/12/html/app-dropdb.html)|
|`-U username`<br/>`--username=username`|接続するユーザ名を指定します|createdb / dropdb|[createdb - PostgreSQL 12.4文書](https://www.postgresql.jp/document/12/html/app-createdb.html)|
|`-O owner`<br/>`--owner=owner`|新しいデータベースの所有者となるデータベースユーザを指定します|createdb||
|`-T template`<br/>`--template=template`|データベースの構築に使用するテンプレートデータベースを指定します。|createdb|[22.3. テンプレートデータベース - PostgreSQL 12.4文書](https://www.postgresql.jp/document/12/html/manage-ag-templatedbs.html)|
|`--lc-collate=locale`|データベースで使用する照合順(LC_COLLATE)指定します。 これは、たとえばORDER BYを持つ問い合わせなどにおいて文字列に適用されるソート順やテキスト型の列に対するインデックスで使用される順序に影響します。|createdb|[CREATE DATABASE - PostgreSQL 12.4文書](https://www.postgresql.jp/document/12/html/sql-createdatabase.html)|
|`--lc-ctype=locale`|データベースで使用する文字のクラス(LC_CTYPE)を指定します。 これは、たとえば小文字、大文字、数字といった文字の分類に影響します。 デフォルトではテンプレートデータベースの文字クラスを使用します。|createdb||
|`-l locale`<br/>`--locale=locale`|データベースで使用されるロケールを指定します。 これは--lc-collateと--lc-ctypeの両方を指定することと等価です。|createdb|[23.3. 文字セットサポート - PostgreSQL 12.4文書](https://www.postgresql.jp/document/12/html/multibyte.html)|


















# 失敗事例
## createdb: database creation failed: ERROR:  new collation (ja_JP.UTF-8) is incompatible with the collation of the template database (en_US.UTF-8)

```bash
$ createdb -e database_name -O user_name -U user_name --lc-collate=ja_JP.UTF-8 --lc-ctype=ja_JP.UTF-8
CREATE DATABASE database_name OWNER user_name LC_COLLATE 'ja_JP.UTF-8' LC_CTYPE 'ja_JP.UTF-8';
createdb: database creation failed: ERROR:  new collation (ja_JP.UTF-8) is incompatible with the collation of the template database (en_US.UTF-8)
HINT:  Use the same collation as in the template database, or use template0 as template.
```

### 原因 : template0を指定しないから
> `CREATE DATABASE korean WITH ENCODING 'EUC_KR' LC_COLLATE='ko_KR.euckr' LC_CTYPE='ko_KR.euckr' TEMPLATE=template0;`
> 上のコマンドにてtemplate0データベースのコピーが指定されていることに注目してください。 他のデータベースからコピーする場合、データが破損する結果となる可能性がありますので、符号化方式とロケール設定を元のデータベースの設定から変更することはできません。
> [23.3. 文字セットサポート - PostgreSQL 12.4文書](https://www.postgresql.jp/document/12/html/multibyte.html)

`--lc-collate`を指定する場合は、「指定する文字クラスと設定が同じデータベース」か「template０（標準オブジェクトのみのテンプレートデータベース）」を作成元のデータベース(テンプレート)として指定しなくてはいけないらしい。

```bash:今回はtemplate0を指定して実行しなおす！
$ createdb -e database_name -O user_name -U user_name -T template0 --lc-collate=ja_JP.UTF-8 --lc-ctype=ja_JP.UTF-8
CREATE DATABASE database_name OWNER user_name TEMPLATE template0 LC_COLLATE 'ja_JP.UTF-8' LC_CTYPE 'ja_JP.UTF-8';
```

## ERROR:  database database_name is being accessed by other users

```sql
postgres=# drop database database_name;
ERROR:  database "database_name" is being accessed by other users
DETAIL:  There are 1 other sessions using the database.
```
### 原因 : 誰かが削除しようとしているデータベースに接続しているから
強制的にセッションを切断します。
でも、周りの人には確認してからやらないと恨まれるかもしれませんのでお気をつけて。

参考 : [PostgreSQL のサーバー側でセッションを切断する方法 - Qiita](https://qiita.com/yteraoka/items/90f61beb1ade1b002a54)

```sql
-- 強制的にセッションを切断
postgres=# SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'database_name' AND pid <> pg_backend_pid();
-- もう一度削除する
postgres=# drop database database_name;
```