平田智剛のブログ

立法、行政、司法、報道、そして科学

F.ism.does_harm_to(!F);

PostgresSQLでデータベース名に日本語を使うのはよくない。

1. ビフォア

環境:
PC: Windows 10
psql.exeのバージョン: Postgres95

僕がsql関係データベース管理システムを利用するときに使うときは、いつもきまって「pgAdmin」という、ブラウザ上で動作するGUIを使っていた。

pgAdmin上では日本語名のデータベースやテーブルを作っても特に咎められることもないのであるが、ここに落とし穴がある。

2. 気づき

日本語名のテーブルを用意して、そこに文字コードUTF8のCSVからデータを読み込もうとしたとき、図2-1のようなエラーが出てつまづいた。

f:id:ec084:20200110155038p:plain 図2-1. 発生したエラー

「実行中のコマンド」にある&#○○;というはhtml10進数unicodeであり、デコードしてみると次のようになり、日本語のデータベース名やテーブル名、列名が復元した。

"C:\\Program Files\\PostgreSQL\\11\\bin\\psql.exe" --command " "\\copy public.\"文献\" (no, \"書誌種別\", \"タイトル\", \"叢書名漢字\", \"著者\", \"出版者\", \"出版年月\", \"分類\", \"在架\") FROM 'D:/daigaku_note/699_2.csv' DELIMITER ',' CSV ENCODING 'UTF8' QUOTE '\"' ESCAPE '''';""

しかし、psql: FATAL: �f�[�^�x�[�X"�}�X�R�~�_"�͑��݂��܂���の方は、utf-8がshift-jisに誤変換されたものらしく、読むことができなかった。

\copy public.文献 (no, 書誌種別, タイトル, 叢書名漢字, 著者, 出版者, 出版年月, 分類, 在架) FROM 'D:/daigaku_note/699_2.csv' DELIMITER ',' CSV ENCODING 'UTF8' QUOTE '\"' ESCAPE '''';
基本はもう一つ上のコマンドの`--command`以降を引っ張ってきた。但し、全体がダブルクォーテーションでくくられているダメなようだったので、それを解除した。 また、QUOTEオプションの`'\"'`は文字列`\"`を表していて、これはダブルクォーテーション`"`をエスケープしたものである。 ESCAPEオプションの`''''`は文字列`''`を表していて、これはシングルクォーテーション`'`をエスケープしたものである。 -->

仕方ないのでpsql.exeをコマンドプロンプトから起動し、ログインし、目的のテーブルの所属するデータベース「マスコミ論」へ入り、上記のコマンドを(一部修正し)打ってみることとした。

しかし、ここで問題が発生した。

\connectコマンドで日本語名のデータベース「マスコミ論」に入ろうとするとエラーになってしまうのだ。(「存在しない」といわれてしまう)

英数字で名付けたデータベースにはアクセスできるし、 \list でデータベースの一覧を表示したらちゃんと存在しているのに、である。

コマンドプロンプトのコードページをUTF8のもの(65001)にあわせても、psql.exe内のオプションで\encoding UTF8を実行しても、

日本語名のデータベースにはアクセスできないようだった。

さらにいろいろ実験すると、
\connect マスコミ論;を実行すると
FATAL: データベース"マスコミ"は存在しませんとかいうくせに、
CREATE DATABASE マスコミ論; をやると
ERROR: データベース"マスコミ論"はすでに存在しますとか言い出すことが分かった

これでは話がめちゃくちゃだ。。。

きっとCtypesjisになっているところが原因でエラーを引き起こしているのだろうが、pgAdminからはなぜかグレーアウトしていて変更できなかった。

3. これから

このエラーと4時間近く戦ったが手も足も出ないので、とりあえず、データベース名には日本語を避けることに決めた。

テーブル名、列名、値でも似たような問題が発生するかどうかは調べていないのでわからない。 テーブル名に関しては問題なさそうだ(図3-1)

f:id:ec084:20200110181013p:plain 図3-1. 「日本語出来るのかな」という名前のテーブルが正常に扱える様子

4. 参考

PostgreSQLで「'」(シングルクォーテーション/単一引用符)をエスケープ処理する方法 - r_nobuホームページ