PG :: Fehler: FEHLER: Neue Codierung (UTF8) ist nicht kompatibel

81

ich habe installiert postgresql-9.2.4 von der Quelle , jetzt in der Rails-App, wenn ich Folgendes ausführe:

rake db:create Befehl, den ich bekomme:

$ bin/rake db:create RAILS_ENV="test"
PG::Error: ERROR:  new encoding (UTF8) is incompatible with the encoding of the template database (SQL_ASCII)
HINT:  Use the same encoding as in the template database, or use template0 as template.
: CREATE DATABASE "verticals_test" ENCODING = 'unicode'
/home/vagrant/my-project/.gems/ruby/1.9.1/gems/activerecord-3.2.12/lib/active_record/connection_adapters/postgresql_adapter.rb:652:in `exec
....
bin/rake:16:in `load'
bin/rake:16:in `<main>'
Couldn't create database for {"adapter"=>"postgresql", "encoding"=>"unicode", "database"=>"my_db", "host"=>"localhost", "pool"=>5, "username"=>"my_user", "password"=>"my_password"}

irgendeine Idee?

tokhi
quelle

Antworten:

229

Ok, die folgenden Schritte haben das Problem behoben:

  1. Zuerst müssen wir template1 löschen. Vorlagen können nicht gelöscht werden, daher ändern wir sie zuerst, sodass es sich um eine normale Datenbank handelt:

    UPDATE pg_database SET datistemplate = FALSE WHERE datname = 'template1';

  2. Jetzt können wir es fallen lassen:

    DROP DATABASE template1;

  3. Jetzt ist es an der Zeit, eine Datenbank aus template0 mit einer neuen Standardcodierung zu erstellen:

    CREATE DATABASE template1 WITH TEMPLATE = template0 ENCODING = 'UNICODE';

  4. Ändern Sie nun template1 so, dass es sich tatsächlich um eine Vorlage handelt:

    UPDATE pg_database SET datistemplate = TRUE WHERE datname = 'template1';

  5. Wechseln Sie nun zu template1 und VACUUM FREEZE die Vorlage:

    \c template1

    VACUUM FREEZE;

Problem sollte gelöst sein.

tokhi
quelle
1
@tokhi Dies ist eine funktionierende Lösung. Ich bin nicht sehr vertraut mit posgresql, aber mein einziger kleiner Schritt 0: sudo -u postgres psql postgresfür debian oder ein ähnliches Betriebssystem.
Croonx
39

Stellen Sie sicher, dass Ihre database.ymlDatei das richtige Setup enthält. Sie sollten verwenden template0, wie der Fehler andeutet:

test:
  adapter: postgresql
  encoding: unicode
  database: your_db_name
  template: template0
  host: localhost
  ...
mihai
quelle
Ich hatte nicht template0in meiner Konfiguration, wenn ich es platziere, bekomme ich:PG::Error: ERROR: permission denied to copy database "template0" : CREATE DATABASE "my_database_test" ENCODING = 'unicode' TEMPLATE = "template0"
Tokhi
das ist seltsam ... verhält es sich für die developmentUmgebung genauso ?
Mihai
3
Könnte jemand den Unterschied zwischen template0 und template1 erklären und warum dies funktioniert?
Jake
@ Jake siehe postgresql.org/docs/10/static/manage-ag-templatedbs.html - alles macht Sinn nach dem Lesen dieser Seite :-)
Markus
11

Wenn Sie Debian verwenden und das Postgresql-Paket installieren, wird Ihr Standardgebietsschema zum Erstellen der Datenbank template1 verwendet. Wenn Sie Ihr Betriebssystem nicht für die Verwendung von UTF-8 als Standardgebietsschema konfiguriert haben, tritt dieser Fehler auf.

Zusätzlich zu den oben genannten Lösungen können Sie, wenn Sie sich in einer Neuinstallation befinden und keine aktiven Datenbanken haben, das postgresql-Paket entfernen und Ihr Standardgebietsschema auf UTF-8 festlegen. Der Vorteil dieser Methode besteht darin, dass Sie beim Erstellen von Datenbanken in Zukunft Gebietsschemainformationen weglassen können.

dpkg-reconfigure locales

Wenn Sie das gewünschte Gebietsschema nicht sehen, installieren Sie das Paket locales-all

apt-get install locales-all

Dann entfernen Sie postgresql

apt-get remove --purge postgresql-<version>

Dann neu installieren oder besser noch auf eine aktuelle Version aktualisieren, die nicht in Debian stabil ist .

Lee
quelle
2
Ich habe mein Standardgebietsschema auf en_US.UTF-8 festgelegt und Ihre Anweisungen zum erneuten Installieren von postgres befolgt. Danach wurde immer noch der gleiche Fehler angezeigt.
Simon Woodside
Stimme Simon zu. Was für eine Zeitverschwendung :(
Karni
Nach der Installation von Locales hat es wie von Zauberhand funktioniert :)
Daniel Gordi vor
6

Ich ändere einfach die Zeile von database.yml:

encoding: unicode

zu:

encoding: SQL_ASCII

genau das und alles funktioniert.

Yakob Ubaidi
quelle
2
Dies ist besser als die akzeptierte Lösung, aber ich bin neu in diesem Bereich, sodass mir die Auswirkungen der Änderung von Unicode in SQL_ASCII möglicherweise nicht bewusst sind.
IndieNik
1
Die Verwendung von SQL_ASCII ist keine gute Standardeinstellung.
Doug
5

Wenn Ihre Postgres-Installation neu ist und Sie noch keine Datenbanken ausgefüllt haben, können Sie Ihr dataVerzeichnis entfernen und den Befehl initdb mit dem Flag erneut ausführen, um Datenbanken mit UTF-8 zu erstellen.

Ändern Sie diesen Befehl entsprechend Ihrer Postgres-Installation. Das -EFlag gibt an, welche Zeichencodierung die Standardeinstellung sein soll. Andere Zeichenkodierungen sind hier aufgelistet .

/usr/local/pgsql/bin/initdb -E UTF8 -D /usr/local/pgsql/data -U postgres

Es sollte ein Fehler auftreten und Ihnen mitteilen, dass das dataVerzeichnis nicht leer ist. Befolgen Sie die Anweisungen, entfernen Sie das Verzeichnis und führen Sie den Befehl erneut aus. (Oder entfernen Sie das dataVerzeichnis, bevor Sie beginnen, aber es ist immer schön, die Anweisungen selbst zu sehen.)

Kleinwald
quelle
2

Ich hatte ein ähnliches Problem. Meine database.yml war wie folgt: -

default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
  <<: *default
  database: chatapp_development

test:
  <<: *default
  database: chatapp_test

production:
  <<: *default
  database: chatapp_production
  username: chatapp
  password: <%= ENV['CHATAPP_DATABASE_PASSWORD'] %>

Ich habe template: template0 zu den Standardeinstellungen hinzugefügt

default: &default
  adapter: postgresql
  template: template0
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

Und es hat funktioniert

Hussain Niazi
quelle
Ah, die Reihenfolge ist wichtig! template: template0 MUSS kommen, bevor encoding: unicodees scheint.
Dan Bechard