Wie ändere ich die Zeichenkodierung einer Postgres-Datenbank?

Antworten:

64

So ändern Sie die Codierung Ihrer Datenbank:

  1. Dump Ihre Datenbank
  2. Löschen Sie Ihre Datenbank,
  3. Erstellen Sie eine neue Datenbank mit der anderen Codierung
  4. Laden Sie Ihre Daten neu.

Stellen Sie sicher, dass die Client-Codierung währenddessen korrekt eingestellt ist.

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

Daniel Kutik
quelle
Was ich über den Link nicht bekomme, ist "Überprüfen Sie, ob die im ersten Schritt erstellte Dump-Datei Sonderzeichen enthält und nehmen Sie die erforderlichen Änderungen vor" => Muss ich alle Sonderzeichen manuell ändern
spankmaster79
1
Können Sie bitte die Befehle zum Speichern und erneuten Importieren zu Ihrer Antwort hinzufügen? wie sudo -u postgres pg_dump your_db > /backups/postgresql.sql...
rubo77
104

Zunächst einmal ist Daniels Antwort die richtige, sichere Option.

Für den speziellen Fall des Wechsels von SQL_ASCII zu etwas anderem können Sie den pg_database-Katalog betrügen und einfach stupsen, um die Datenbankcodierung neu zuzuweisen. Dies setzt voraus, dass Sie bereits Nicht-ASCII-Zeichen in der erwarteten Codierung gespeichert haben (oder dass Sie einfach keine Nicht-ASCII-Zeichen verwendet haben).

Dann können Sie tun:

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

Dies ändert nichts an der Sortierung der Datenbank, sondern nur daran, wie die codierten Bytes in Zeichen konvertiert werden (daher wird jetzt length('£123')4 statt 5 zurückgegeben). Wenn die Datenbank die C-Sortierung verwendet, sollte die Reihenfolge für ASCII-Zeichenfolgen nicht geändert werden. Sie müssen jedoch wahrscheinlich alle Indizes neu erstellen, die Nicht-ASCII-Zeichen enthalten.

Vorbehalt Emptor. Durch Dumping und Neuladen können Sie überprüfen, ob der Inhalt Ihrer Datenbank tatsächlich in der von Ihnen erwarteten Codierung vorliegt. Dies ist jedoch nicht der Fall. Und wenn sich herausstellt, dass Sie einige falsch codierte Daten in der Datenbank hatten, wird die Rettung schwierig. Also, wenn Sie können, entleeren und neu initialisieren.

araqnid
quelle
1
+1 Danke. Meine Entwicklungsmaschine verwendet UTF8-Enconding, aber meine Produktion verwendet LATIN1. Aus diesem Grund hatte ich viele Fehler.
Luiz Damim
1
Es gibt mir diesen Fehler: -bash: syntax error near unexpected token ('`
Abhipso Ghosh
@AbhipsoGhosh dies soll nicht in eine Bash-Shell eingefügt werden, sondern an der psqlEingabeaufforderung.
Pierre
14

Wenn Sie eine Datenbank mit einer bestimmten Codierung sichern und versuchen, sie in einer anderen Datenbank mit einer anderen Codierung wiederherzustellen, kann dies zu einer Beschädigung der Daten führen. Die Datencodierung muss eingestellt werden, bevor Daten in die Datenbank eingefügt werden.

Überprüfen Sie dies : Wenn andere Datenbank zu kopieren, die Codierung und Locale - Einstellungen können nicht von denen der Quelldatenbank geändert werden, denn das ist in korrupten Daten führen könnte.

Und das : Bei einigen Gebietsschema-Kategorien müssen die Werte beim Erstellen der Datenbank festgelegt werden. Sie können unterschiedliche Einstellungen für unterschiedliche Datenbanken verwenden. Sobald eine Datenbank erstellt wurde, können Sie sie für diese Datenbank nicht mehr ändern. LC_COLLATE und LC_CTYPE sind diese Kategorien. Sie wirken sich auf die Sortierreihenfolge der Indizes aus, daher müssen sie festgehalten werden, da sonst die Indizes für Textspalten beschädigt werden. ( Sie können diese Einschränkung jedoch mithilfe von Kollatierungen aufheben , wie in Abschnitt 22.2 erläutert. ) Die Standardwerte für diese Kategorien werden beim Ausführen von initdb festgelegt. Diese Werte werden beim Erstellen neuer Datenbanken verwendet, sofern im Befehl CREATE DATABASE nichts anderes angegeben ist.


Ich würde lieber alles von Anfang an richtig mit einer korrekten lokalen Codierung auf Ihrem Debian-Betriebssystem neu erstellen, wie hier erklärt :

su root

Konfigurieren Sie Ihre lokalen Einstellungen neu:

dpkg-reconfigure locales

Wählen Sie Ihr Gebietsschema (wie zum Beispiel für Französisch in der Schweiz: fr_CH.UTF8)

Postgresql deinstallieren und ordnungsgemäß reinigen:

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 neu installieren:

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

Jetzt wird jede neue Datenbank automatisch mit der richtigen Codierung, LC_TYPE (Zeichenklassifizierung) und LC_COLLATE (Zeichenfolgensortierreihenfolge) erstellt.

Douglas
quelle
2
Ich denke, es ist "dpkg-Rekonfigurieren von Gebietsschemas", Plural. Die Singularform scheint nicht zu funktionieren (nur überprüft).
foo
9

Die Antwort von Daniel Kutik ist richtig, aber mit der Umbenennung der Datenbank kann sie noch sicherer sein .

Der wirklich sichere Weg ist also:

  1. Erstellen Sie eine neue Datenbank mit der anderen Codierung und dem anderen Namen
  2. Dump Ihre Datenbank
  3. Stellen Sie den Speicherauszug in der neuen Datenbank wieder her
  4. Testen Sie, ob Ihre Anwendung mit der neuen Datenbank ordnungsgemäß ausgeführt wird
  5. Benennen Sie die alte Datenbank in etwas Sinnvolles um
  6. Neue Datenbank umbenennen
  7. Anwendung erneut testen
  8. Löschen Sie die alte Datenbank

Benennen Sie im Notfall einfach die DBs zurück

Sergey Zarubin
quelle
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"   
rubo77
quelle