-
2024-02-20 PostgreSQLPostgreSQL ナレッジPostgreSQL パラメータ
PostgreSQLの client_encoding パラメータを変更する方法
PostgreSQL のパラメータに client_encoding というものがあります。
これは名前のとおり、クライアントのエンコーディングを制御するものです。
データを追加や参照した際に文字化けが発生した場合などに、よく確認/変更するパラメータとなっています。
本記事では、この client_encoding を変更する方法について、色々と確認した結果を記載しています。
確認に使った環境
本記事内での確認に使った環境は
- Ubuntu 22.04
- PostgreSQL 16.2
です。
postgresql.conf と実際に設定されている値の確認
まずは client_encoding の値を確認します。
postgresql.conf の記述を見てみると、client_encoding はコメントアウトされていました。
また、デフォルト値は sql_ascii であることを確認しました。
$ grep "client_encoding" ./postgresql.conf
#client_encoding = sql_ascii # actually, defaults to database
では実際にデータベースクラスタに psql で接続し、設定されている値を確認します。
postgres=# SHOW client_encoding;
client_encoding
-----------------
UTF8
(1 row)
デフォルト値は sql_ascii ですが、実際に client_encoding に設定されている値は UTF8 となっていました。
これは、psql の仕様のようで、公式ドキュメントに説明がありました。
下記に引用します。
【 PostgreSQL 文書 15.4 - psql - 】
https://www.postgresql.jp/document/15/html/app-psql.html#R2-APP-PSQL-CONNECTING
標準入力および標準出力の両方が端末である場合、psqlはクライアントの符号化方式を「auto」に設定します。 これはロケール設定(Unixシステムでは環境変数LC_CTYPE)から適切なクライアント符号化方式を決定します。 想定した通りに動作しない場合、環境変数PGCLIENTENCODINGを使用してクライアント符号化方式を上書きすることができます。
どうやら OS の LC_CTYPE の設定から client_encoding が決定されているため、UTF8 となっているようです。
念の為、postgresql.conf の client_encoding に SJIS を設定しても、実際の設定値は UTF8 のままかを確認します。
$ grep "client_encoding" ./postgresql.conf
#client_encoding = sql_ascii # actually, defaults to database
client_encoding = SJIS
忘れずに PostgreSQL を再読み込みしてから、psql で接続して client_encoding の値を確認します。
$ pg_ctl reload
server signaled
$ psql -c "SHOW client_encoding;"
client_encoding
-----------------
UTF8
(1 row)
想定通り client_encoding は UTF8 のままでした。
client_encoding パラメータを変更する方法
単純に postgresql.conf の client_encoding を変更するだけでは、変わりませんでした。
ではタイトルにもあるように、どうすれば client_encoding パラメータを変更できるのか、ということになりますが、上記に引用した
想定した通りに動作しない場合、環境変数PGCLIENTENCODINGを使用してクライアント符号化方式を上書きすることができます。
というもの以外に、公式ドキュメント上の別の説明箇所で、いくつかの方法が記載されていました。
その該当部分を、下記に列挙します。
【 PostgreSQL 15.4 文書 - 24.3. 文字セットサポート - 】
https://www.postgresql.jp/document/15/html/multibyte.html#id-1.6.11.5.8
- psqlで\encodingコマンドを使う。
- libpq のクライアントの符号化方式を制御する関数を使う。
- SET client_encoding TOを使う。
- client_encoding変数を使う。
以下では、環境変数 PGCLIENTENCODING を利用して、client_encoding を変更できるかを実際に確認します。
環境変数 PGCLIENTENCODING を変更する
まずは、クライアント側で環境変数 PGCLIENTENCODING に SJIS を設定します。
$ export PGCLIENTENCODING=SJIS
この状態で psql で接続して、実際に client_encoding に設定されている値を確認します。
postgres=# SHOW client_encoding;
client_encoding
-----------------
SJIS
(1 row)
無事に client_encoding も sjis となりました。
postgresql.conf に設定した client_encoding を適用する方法
クライアント側の環境変数 PGCLIENTENCODING に設定した値が、client_encoding に設定されることを確認できました。
ただ、そうであれば postgresql.conf の client_encoding は何のためにあるのか、という疑問が生まれます。
このあたりの説明については、公式ドキュメント等を確認しましたが、明確に説明されている記述を見つけられませんでした。
手元の環境で色々と試したところ、環境変数 PGCLIENTENCODING が未定義、未指定、設定あり、の場合で、挙動が変わるということを確認できました。
この未定義というのは
$ unset PGCLIENTENCODING
した後の状態を想定しています。
未指定というのは
$ export PGCLIENTENCODING=
という状態を想定しています。
環境変数 PGCLIENTENCODING が未指定
具体的に、環境変数 PGCLIENTENCODING が未指定の場合の挙動を確認します。
postgresql.conf の client_encoding は SJIS となっています。
$ export PGCLIENTENCODING=
$ psql
psql (16.2)
Type "help" for help.
postgres=# SHOW client_encoding;
client_encoding
-----------------
SJIS
(1 row)
上記の通り、環境変数 PGCLIENTENCODING が未指定('')の場合には、postgresql.conf の client_encoding の値が設定されるようです。
確認結果
確認結果をまとめると、下記の表のようになります。
postgresql.conf の client_encoding | クライアント側の環境変数 PGCLIENTENCODING | psql で接続した際の client_encoding |
---|---|---|
sql_ascii | 未定義 | UTF8(※) |
sql_ascii | 未指定('') | UTF8(※) |
sql_ascii | SJIS | SJIS |
sql_ascii | UTF8 | UTF8 |
SJIS | 未定義 | UTF8(※) |
SJIS | 未指定('') | SJIS |
SJIS | SJIS | SJIS |
SJIS | UTF8 | UTF8 |
※ クライアント側の OS の LC_CTYPE によって、変動します。
つまり、psql で PostgreSQL に接続した際、client_encoding には
- 環境変数 PGCLIENTENCODING が指定されている場合、PGCLIENTENCODING の値が設定
- 環境変数 PGCLIENTENCODING が未指定の場合、postgresql.conf の client_encoding の値が設定
- 環境変数 PGCLIENTENCODING が未定義の場合、クライアント側の OS の LC_CTYPE によって設定
されることになるようです。
まとめ
以上が client_encoding パラメータを変更する方法となります。
繰り返しとなりますが、環境変数 PGCLIENTENCODING が未定義、未指定、設定ありで、挙動が変わるというのは、公式ドキュメント等で説明されている記述を見つけられていません。
あくまで、こちらの手元で検証した結果となりますので、お使いの環境では異なる挙動となる可能性があることにご注意ください。