postgresデータベースの文字エンコードをどのように変更しますか?


82

デフォルトの文字セットSQL_ASCIIでセットアップされたデータベースがあります。UNICODEに切り替えたい。それを行う簡単な方法はありますか?



回答:


64

データベースのエンコーディングを変更するには:

  1. データベースをダンプします
  2. データベースを削除し、
  3. 異なるエンコーディングで新しいデータベースを作成する
  4. データをリロードします。

この間、クライアントのエンコーディングが正しく設定されていることを確認してください。

出典:http//archives.postgresql.org/pgsql-novice/2006-03/msg00210.php


リンクから取得できないのは、「最初のステップで作成したダンプファイルに特殊文字が含まれているかどうかを確認し、必要な変更を行う」=>すべての特殊文字を手動で変更する必要があるか
spankmaster79 2016年

1
ダンプして再インポートするコマンドを回答に追加していただけますか?以下のようなsudo -u postgres pg_dump your_db > /backups/postgresql.sql...
rubo77

104

まず、ダニエルの答えは正しい、安全なオプションです。

SQL_ASCIIから他の何かに変更する特定のケースでは、pg_databaseカタログをごまかして単純に突くと、データベースエンコーディングを再割り当てできます。これは、期待されるエンコーディングで非ASCII文字がすでに格納されている(または単に非ASCII文字を使用していない)ことを前提としています。

次に、次のことができます。

update pg_database set encoding = pg_char_to_encoding('UTF8') where datname = 'thedb'

これにより、データベースの照合順序は変更されず、エンコードされたバイトが文字に変換される方法が変更されます(したがってlength('£123')、5ではなく4が返されます)。データベースが「C」照合を使用する場合、ASCII文字列の順序に変更はありません。ただし、非ASCII文字を含むインデックスを再構築する必要がある可能性があります。

買い手責任負担。ダンプとリロードは、データベースのコンテンツが実際に期待するエンコーディングになっていることを確認する方法を提供しますが、そうではありません。また、データベースに誤ってエンコードされたデータがあることが判明した場合、救助は困難になります。したがって、可能であれば、ダンプして再初期化してください。


1
+1ありがとうございます。私の開発マシンはUTF8encondingを使用していますが、本番環境ではLATIN1を使用しています。このため、私は多くのエラーを抱えていました。
ルイスダミム2011

1
それは私にこのエラーを与えています:(-bash: syntax error near unexpected token '`
Abhipso Ghosh 2017

@AbhipsoGhoshこれはbashシェルに貼り付けられることは想定されていませんが、psqlプロンプトで貼り付けられます。
ピエール

14

特定のエンコーディングでデータベースをダンプし、別のエンコーディングで別のデータベースに復元しようとすると、データが破損する可能性があります。データをデータベースに挿入する前に、データエンコーディングを設定する必要があります。

これを確認してください: 他のデータベースをコピーする場合、データが破損する可能性があるため、エンコードとロケールの設定をソースデータベースの設定から変更することはできません。

そしてこれ一部のロケールカテゴリでは、データベースの作成時に値を固定する必要があります。データベースごとに異なる設定を使用できますが、データベースが作成されると、そのデータベースの設定を変更することはできなくなります。LC_COLLATEとLC_CTYPEはこれらのカテゴリです。これらはインデックスの並べ替え順序に影響するため、固定しておく必要があります。そうしないと、テキスト列のインデックスが破損します。ただし、セクション22.2で説明するように、照合を使用してこの制限を緩和できますこれらのカテゴリのデフォルト値はinitdbの実行時に決定され、CREATE DATABASEコマンドで特に指定されていない限り、これらの値は新しいデータベースの作成時に使用されます。


ここで説明するように、Debian OSで正しいローカルエンコーディングを使用して、最初からすべてを適切に再構築したいと思います

su root

ローカル設定を再構成します。

dpkg-reconfigure locales

ロケールを選択します(たとえば、スイスのフランス語の場合:fr_CH.UTF8)

postgresqlを適切にアンインストールしてクリーンアップします。

apt-get --purge remove postgresql\*
rm -r /etc/postgresql/
rm -r /etc/postgresql-common/
rm -r /var/lib/postgresql/
userdel -r postgres
groupdel postgres

postgresqlを再インストールします:

aptitude install postgresql-9.1 postgresql-contrib-9.1 postgresql-doc-9.1

これで、新しいデータベースは、正しいエンコーディング、LC_TYPE(文字分類)、およびLC_COLLATE(文字列のソート順)で自動的に作成されます。


2
複数形の「dpkg-reconfigurelocales」だと思います。単数形は機能していないようです(チェックしただけです)。
foo

9

Daniel Kutikの答えは正しいですが、データベースの名前を変更することで、さらに安全になる可能性があります

したがって、本当に安全な方法は次のとおりです。

  1. 異なるエンコーディングと名前で新しいデータベースを作成します
  2. データベースをダンプします
  3. ダンプを新しいDBに復元します
  4. アプリケーションが新しいDBで正しく実行されることをテストします
  5. 古いDBの名前を意味のある名前に変更します
  6. 新しいDBの名前を変更する
  7. アプリケーションを再度テストします
  8. 古いデータベースを削除します

緊急の場合は、DBの名前を元に戻すだけです


7
# dump into file
pg_dump myDB > /tmp/myDB.sql

# create an empty db with the right encoding (on older versions the escaped single quotes are needed!)
psql -c 'CREATE DATABASE "tempDB" WITH OWNER = "myself" LC_COLLATE = '\''de_DE.utf8'\'' TEMPLATE template0;'

# import in the new DB
psql -d tempDB -1 -f /tmp/myDB.sql

# rename databases
psql -c 'ALTER DATABASE "myDB" RENAME TO "myDB_wrong_encoding";' 
psql -c 'ALTER DATABASE "tempDB" RENAME TO "myDB";'

# see the result
psql myDB -c "SHOW LC_COLLATE"   
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.