タイトル:「WSLにPostgreSQLをinstallすると、デフォルトのEncoding(文字コード)がSQL_ASCIIになってしまう問題の解決方法(UTF8に変更、Debian系、WSL2)」
※初めは丁寧語(敬体)で書いていたのですが、逆に読みづらくなってしまったので常体に変更しました。
劇的BeforeAfter
Before
After
結論
- PostgreSQLのデフォルト文字コードは、Linuxのlocaleを参照する
- WSLはデフォルトの状態だと、rootユーザーは「Cロケール」になってしまっている。この状態だと、PostgreSQLをインストールしたときに、文字コードが「SQL_ASCII」になってしまい、とても不便。
- PostgreSQLはrootユーザーとして操作するため、rootユーザーのlocaleを参照する。そのため、一般ユーザーのlocaleだけを変更しても意味がない。
- localeの変更は
LANG
環境変数だけでなく、LC_ALL
も変更する必要がある
根本的な解決方法
rootユーザー側でlocaleを確認する
su - locale
rootユーザーでdpkg-reconfigure locales
を実行してLANGを変更する
su - dpkg-reconfigure locales
dpkgの操作は、矢印キーで「言語と文字コード」を選んで、スペースキーで「*」を付けたまま、エンターキーを打つ。
そして、もう一度「言語と文字コード」を選んでから、エンターキーを打つと設定される(GUI操作なのでちょっと注意が必要)。
Debian - ロケール(日本語)環境の設定 - Linux入門 - Webkaru
rootユーザーと一般ユーザーの両方でやっておく。
defaultのlocale設定ファイルをsudo vim で書き換えて、LC_ALL=C
のC
を削除して保存する
cd /etc/default ls # localeファイルがあるか確認 cp locale /任意のフォルダ # バックアップを一応取っておく sudo vim locale #LC_ALL=Cの「C」の部分だけを削除する(イコール記号「=」は残す) cat locale # 変更を確認 su - locale # rootユーザーのまま再度確認 exit
PostgreSQLをpurgeして再インストールする
su - apt purge postgre* exit sudo apt autoremove sudo apt list --installed # インストールしたパッケージの確認 sudo apt update sudo apt upgrade # 後はMicrosoftの公式ドキュメントの通りに sudo apt install postgresql postgresql-contrib
WSL を使用してデータベースを追加または接続する | Microsoft Docs
以上の操作をおこなうと、デフォルトの文字コードがUTF8になる
psql シェルで、
postgres=# \l
をおこなうと、encoding(文字コード)などが確認できる
別の解決方法
template1の文字コードを変更する。新しく作成するDBは「template1」の設定を元に作られるため、ここを変更しておけば何とかなる。
【PostgreSQL】データベースの文字コードを変更する | PostgresWeb - ポスグレウェブ
【PostgreSQL】template1の文字コードを変更する | PostgresWeb - ポスグレウェブ
PostgreSQL: template1 のエンコーディングを UTF-8 に変更する - tkrdの日記
PostgreSQLでデフォルトのEncoding・Collate・Ctypeなどを変更したい
あるいは、新しいDBを作成するたびに文字コードなどを色々指定する。
PostgreSQL データベースの作成 - Kakiro-Web カキローウェブ
ターミナルで日本語(全角文字)が入力できないとき
sudo apt install postgresql-contrib
をちゃんとしているか?(contribパッケージをインストールし忘れていないか?)文字コードの設定がUTF8になっているか?
一旦PostgreSQLを再起動したか?
sudo service postgresql restart
なぜこの問題に気づいたか?
WSL2にインストールしたPostgreSQLに、Windows側(VSCodeの拡張機能)から接続したあと、DB(データベース)を読み込もうとしたとき、次のようなエラーが出て疑問に思ったため。
Started executing query at Line 1 Commands completed successfully Unhandled exception while executing query: 'ascii' codec can't decode byte 0xe3 in position 0: ordinal not in range(128) Total execution time: 00:00:00.007
このエラーメッセージを読んで、ascii(アスキー文字)になっていることに気づきました。
WSL2でPostgreSQLを起動し、psqlの操作画面で
postgres=# \l
と入力したところ、
Encoding |Collate |Ctype SQL_ASCII |C |C
になっていた。
ロケール参照について
このサイトに
テンプレートデータベースの符号化方式を選択します。 これが今後作成される全てのデータベースについてのデフォルト符号化方式となりますが、作成時に上書きすることもできます。 デフォルトは、ロケールから取得しますが、取得できなければSQL_ASCIIになります。 PostgreSQLサーバによってサポートされる文字セットについては23.3.1で説明します。
と書いてあったため分かりました。
また、これらの記事も参考になりました。
第1章 PostgreSQLの今昔を知る―20年を超える歴史,リリースサイクル,環境構築:詳解 PostgreSQL[10/11対応]―現場で役立つ新機能と実践知識|gihyo.jp … 技術評論社
PostgreSQLはinitdbの際にロケールを指定しない場合,OS側に設定されているロケールを使用します。
Debian系でPostgreSQLのロケールを変更する - Qiita
initdbのデフォルト値として、ロケールは実行時のLANG環境変数等が、エンコーディングはロケールから推測するかSQL_ASCIIが使われます。
PostgreSQL 9.1 installation and database encoding - Stack Overflow
なぜSQL_ASCIIのままだとマズいのか
SQL_ASCIIのままだと、半角文字しかDBに登録することができない。実際にDBに登録していくときは、日本語のような全角文字も入力するわけで、このままだと様々な問題が生じてしまう。
そのため、あらゆる言語を入力できる「UTF8」に変える必要がある。
ちなみに、PostgreSQLの表記では、大文字の「UTF8」でハイフンは要らないので注意。
Don't Do This - PostgreSQL wiki
Debianのlocalファイルの位置を調べた方法
postgresql - How do I change the default client_encoding in Postgres? - Stack Overflow
の記事を読んで、
The method for doing this may vary depending on your system, but usually you can do it by modifying ~/.config/locale.conf (your user only) or /etc/default/locale or /etc/locale.conf (system-wide). This will affect more than just postgres, and I believe more closely addresses the root of the problem. You can check your current locale settings by running locale.
と書いてあったので、/etc/default/locale
にrootユーザーのlocale設定が置いてあることが分かった。
ここでLC_ALL=C
をLC_ALL=
に変えてあげれば、ロケール設定がうまくいく。
他にも以下のような記事を参考にした。
How to Change or Set System Locales in Linux
command line - How do I change the default locale in Ubuntu Server? - Ask Ubuntu
システムワイドなロケール設定 〜 Debian GNU/Linux - 彷徨えるフジワラ
今回の調査の課題点
initdbコマンドを使えば初期設定の文字コードを変更できるみたいですが、どうやって使えば良いのかよく分かりませんでした(Debianを使っているからかもしれません)。時間のあるときに調べようと思いました。
PostgreSQLの初期設定 | Netsphere Laboratories https://www.nslabs.jp/postgresql-setup.rhtml
今回の教訓
Linuxのrootユーザーの設定(システム設定)と一般ユーザー設定には違いがあることが多いので注意する。
エラーが起きた場合は、それぞれの設定を確認する。