Назад | Перейти на главную страницу

PostGreSQL: проблема с кодировкой при созданииb и LC_ALL = C

У меня есть сценарий, который запускает следующую команду для создания базы данных:

createdb --template template0 -E SQL_ASCII foobar

Я получаю сообщение об ошибке:

createdb: database creation failed: ERROR:  encoding SQL_ASCII does not match locale en_US.UTF-8
DETAIL:  The chosen LC_CTYPE setting requires encoding UTF8.

Я могу понять, почему языковой стандарт может быть проблемой, поэтому я решил установить LC_ALL=C но все равно не работает:

$ LC_ALL=C createdb --template template0 -E SQL_ASCII gnattracker
createdb: database creation failed: ERROR:  encoding SQL_ASCII does not match locale en_US.UTF-8
DETAIL:  The chosen LC_CTYPE setting requires encoding UTF8.

У вас есть идеи, в чем может быть проблема?

Я использую Fedora 13

Спасибо voretaq7, теперь разбираюсь в проблеме.

Итак, что это такое?

Проблема в том, что createdb v не читает переменную окружения LC_ALL когда используется база данных шаблонов. С флагом -e мы можем видеть, что он выдает серверу следующую команду:

CREATE DATABASE gnattracker ENCODING 'SQL_ASCII' TEMPLATE template0;

В этом конкретном случае информация о языковом стандарте из шаблона используется для новой базы данных. И кодировка несовместима с этими настройками локали. Вероятно, потому что LC_ALL не был установлен C когда базы данных были инициализированы с initdb.

Простым решением было бы изменить настройки локали с template0. Итак, я попробовал:

ALTER DATABASE template0 SET LC_CTYPE TO 'C';
ALTER DATABASE template0 SET LC_COLLATE TO 'C';

Проблема в том, что настройки локали вообще нельзя изменить. Невезение. Итак, я решил клонировать template0 с новыми настройками локали и замените существующие template0 со своим клоном:

CREATE DATABASE template0b TEMPLATE template0 LC_COLLATE 'C' LC_CTYPE 'C';
DROP   DATABASE template0;
ALTER  DATABASE template0b RENAME TO template0;

Самое главное - сказать PostGreSQL, что template0 является шаблоном, и вам не нужно быть владельцем базы данных, чтобы его скопировать:

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

Это решило мою проблему (см. также эту проблему).

Проверьте другие переменные среды вашей локали и / или посмотрите http://www.postgresql.org/docs/8.4/static/locale.html о том, как переопределить настройку локали.