orthopedics manic buying avodart rate injection cheap bactrim developmental direct order buspar contamination late buy cephalexin now sexual Death cipro no rx cardiopulmonary clomid without prescription strabismus diphtheria clonidine credentialing
Chronosbox

Migrando bases de dados LATIN1 para UTF-8 com o PostgreSQL

by on Segunda, 08 Março/2010, under Databases, Debian/Ubuntu, Dicas, Gentoo, Linux, PostgreSQL, Servidores

Nos dias atuais é um padrão que todos os sites e servidores web rodem ao menos com UTF-8 como encoding default, entretanto pode-se encontrar casos onde ainda se roda LATIN1 ou até mesmo ASCII.

O caso que tratamos hoje é de um servidor Debian, versão 5.0.3 (lenny), que usava o encode LATIN1 quando instalado e configurado o Postgresql, e não me deixava criar uma base de dados UTF-8, gerando o seguinte erro:

debian:~# su postgres -c 'createdb teste3  -E UTF-8'
createdb: database creation failed: ERROR:  encoding UTF8 does not match server's locale en_US
DETAIL:  The server's LC_CTYPE setting requires encoding LATIN1.

Porque??

O Postgresql, quando roda pela primeira vez, cria um cluster usando o encode default do sistema, e após feito isso, não se pode alterar o encode do cluster. O cluster default é o main, em todas as intalações que eu vi.

No caso deste servidor o encode default (locales) era en_US, que para o Debian significa en_US.ISO-8859-1. Por default o Debian Lenny, nas minhas instalações do zero, usa en_US.UTF-8, então o servidor provavelmente deveria ser um antigo Debian Etch atualizado.

A solução

Depois de alguma pesquisa, descobri que, após configurar o encode do servidor para usar UTF-8, poderia criar um novo cluster que suportasse tal encode.

Vamos ao passo a passo da solução do problema.

  • Criando um novo cluster: Para criar um novo cluster no Debian, é bastante simples:
    debian:~# pg_createcluster 8.3 utf8_cluster
    Creating new cluster (configuration: /etc/postgresql/8.3/utf8_cluster, data: /var/lib/postgresql/8.3/utf8_cluster)...
    Moving configuration file /var/lib/postgresql/8.3/utf8_cluster/postgresql.conf to /etc/postgresql/8.3/utf8_cluster...
    Moving configuration file /var/lib/postgresql/8.3/utf8_cluster/pg_hba.conf to /etc/postgresql/8.3/utf8_cluster...
    Moving configuration file /var/lib/postgresql/8.3/utf8_cluster/pg_ident.conf to /etc/postgresql/8.3/utf8_cluster...
    Configuring postgresql.conf to use port 5433...
     
    debian:~# /etc/init.d/postgresql-8.3 restart

    O cluster vai rodar na primeira porta livre que achar depois da 5432, a não ser que você especifique. Para ter efeito, reinicia-se o Postgresql.

  • Criando o usuário: Agora crie o usuário da base de dados, recomendo o mesmo nome e senha além de editar sua autenticação para trust no pg_hba.conf do seu cluster:
    debian:~# su postgres -c "createuser -P pyuser -p 5433"
    Enter password for new role:
    Enter it again:
    Shall the new role be a superuser? (y/n) n
    Shall the new role be allowed to create databases? (y/n) n
    Shall the new role be allowed to create more new roles? (y/n) n
  • Migrando as bases: Agora você deve migrar as bases de dados. Primeiro crie ela e depois faça um dump seguido de um psql, direto na linha de comando. Siga o exemplo:
    debian:~# su postgres -c "createdb teste3 -e -p 5433 -O pyuser"
    CREATE DATABASE teste3 OWNER pyuser;

    Agora liste a base de dados:

    debian:~# su postgres -c "psql -l -p 5433"
            List of databases
       Name    |  Owner   | Encoding
    -----------+----------+----------
     postgres  | postgres | UTF8
     template0 | postgres | UTF8
     template1 | postgres | UTF8	
     teste3    | pyuser   | UTF8
    (4 rows)

    Após criar a base de dados, então faremos a população dela, atenção quanto as portas:

    debian:~# pg_dump -U pyuser teste3 | psql -U pyuser -p 5433 teste3
  • Configurando sua aplicação: Esta é a parte mais simples, apenas altere a porta da sua aplicação para a porta do novo cluster.

Repita os passos da criação da base de dados para cada base que precisa ser movida, e pronto, tudo funcionando agora com suporte a UTF-8.

:, , , , , , , , , , , ,

4 Comments for this entry

  • marc

    Hello! Your post (Moving PostgreSQL databases from LATIN1 to UTF-8 – Chronosbox) does so well that I would like to translate it into French, publish on my french blog and link to you. You have something against it? Regards

  • Marc PC1MH

    Hi,
    Thanks for the help.
    I had the same problem and solved it in a slightly different way. I’d like to share with you all the following:

    If the database is in LATIN1 and the data is in UTF-8 then:

    createdb: database creation failed: ERROR: encoding UTF8 does not match server’s locale en_US
    DETAIL: The server’s LC_CTYPE setting requires encoding LATIN1.

    - purge postgres (apt-get purge postgres postgres-common)
    - check out /etc/locale.gen and add: en_US.UTF-8 UTF-8
    - Then run as root: locale-gen
    - Reinstall postgres and now all databases are in UTF-8

  • Eberson

    Cara Muito boa sua dica, testei e cria o cluster 100%, mas o meu caso é assim so estou arrumando um servidor de dados em lenny o programador nao esta aqui portanto nao consiogo mudar a porta da aplicação :) será que nao tem como mudar a configuração default do postgre pra usar a codificação utf8??? Se vc puder dar uma dica agradeceria…

    • Felipe 'chronos' Prenholato

      Oi Eberson, desculpa a demora para responder. Se eu não me engano (não to com um postgres agora para checar, pois mudei de trabalho) cada cluster tem um arquivo postgresql.conf. Você indo nestes arquivos e editando a configuração port, e depois restartando o postgresql, deve resolver o seu problema.

Leave a Reply

StatPress

Visits today: 5 Visits since 6 de abril de 2009: 87422 Visitors now: %visitoronline%