PostgreSQL の文字コードを LATIN1 から UTF8 に修正する方法
はじめに
新しく用意した Ubuntu サーバに PostgreSQL をインストールして使おうとしたところ、以下のエラーが発生しました。
PG::InvalidParameterValue: ERROR: encoding "UTF8" does not match locale "en_US"
DETAIL: The chosen LC_CTYPE setting requires encoding "LATIN1".
データベースにログインして文字コードとロケールを確認してみると、以下のようになっていました。
$ sudo -u postgres psql
psql (9.5.10)
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+---------+-------+-----------------------
postgres | postgres | LATIN1 | en_US | en_US |
template0 | postgres | LATIN1 | en_US | en_US | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | LATIN1 | en_US | en_US | =c/postgres +
| | | | | postgres=CTc/postgres
(3 rows)
あれ、文字コードが LATIN1 になっている!
Ubuntu サーバにインストールした PostgreSQL の文字コードを UTF8 に変更する方法を紹介します。なお、CentOS の場合は、initdb
コマンド実行時に文字コードやロケールの設定をオプションで追加できるので、そちらをお調べください。
環境
- Ubuntu 16.04 xenial
- PostgreSQL 9.5.10
手順
PostgreSQL サービスが起動している場合は停止させます。
$ sudo systemctl stop postgresql
次に、PostgreSQL クラスタを削除します。9.5
には、お使いの PostgreSQL のバージョンを入れてください。以降の 9.5
も適宜、置き換えてください。
$ sudo pg_dropcluster --stop 9.5 main
環境変数の言語を en_US.UTF-8
に変更します。
$ export LANGUAGE="en_US.UTF-8"
$ export LANG="en_US.UTF-8"
$ export LC_ALL="en_US.UTF-8"
先ほど停止させた PostgreSQL サービスを起動します。
$ sudo systemctl start postgresql
PostgreSQL クラスタを、文字コード UTF8 として作成します。
$ sudo pg_createcluster -e UTF8 --start 9.5 main
以下のように表示されれば OK です。
Creating new cluster 9.5/main ...
config /etc/postgresql/9.5/main
data /var/lib/postgresql/9.5/main
locale en_US.UTF-8
socket /var/run/postgresql
port 5432
Redirecting start request to systemctl
必要ないかもしれませんが、念のため PostgreSQL サービスを再起動しておきます。
$ sudo systemctl restart postgresql
では、文字コードが UTF8 になったか確認してみましょう。
$ sudo -u postgres psql
psql (9.5.10)
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
(3 rows)
無事、意図した初期設定になりました!
まとめ
今まで使ってきたサーバは、このようなことをしなくてもデフォルトで UTF8 になっていたため、なぜ、今回使用したサーバは、デフォルトが LATIN1 になっていたのかわかりません。
しかも、CentOS の場合は、initdb
コマンド実行時にオプションを指定できるので、まだ良いですが、Ubuntu の場合は initdb
コマンドが存在しないです。(つまり実行する必要もないです)
どうやら、Ubuntu の場合は、PostgreSQL をインストールした時点で、勝手に初期の文字コードやロケールが決まってしまうみたいなので、厄介です。
こんなことは PostgreSQL の環境構築をしていてはじめて起こりましたが、同じような問題に直面している人の参考になれば幸いです。
Discussion