¿Cómo se cambia la codificación de caracteres de una base de datos de postgres?

Respuestas:

64

Para cambiar la codificación de su base de datos:

  1. Descarga tu base de datos
  2. Suelta tu base de datos,
  3. Crea una nueva base de datos con diferentes codificaciones.
  4. Recargue sus datos.

Asegúrese de que la codificación del cliente esté configurada correctamente durante todo esto.

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

Daniel Kutik
fuente
Lo que no obtengo del enlace es "Verifique si el archivo de volcado creado en el primer paso tiene algún carácter especial y realice los cambios necesarios" => ¿Tengo que cambiar manualmente todos los caracteres especiales?
spankmaster79
1
¿Puede agregar los comandos para volcar y reimportar a su respuesta? como sudo -u postgres pg_dump your_db > /backups/postgresql.sql...
rubo77
104

En primer lugar, la respuesta de Daniel es la opción correcta y segura.

Para el caso específico de cambiar de SQL_ASCII a otra cosa, puede hacer trampa y simplemente pinchar el catálogo pg_database para reasignar la codificación de la base de datos. Esto supone que ya ha almacenado cualquier carácter que no sea ASCII en la codificación esperada (o que simplemente no ha utilizado ningún carácter que no sea ASCII).

Entonces puedes hacer:

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

Esto no cambiará la clasificación de la base de datos, solo cómo los bytes codificados se convierten en caracteres (por lo que ahora length('£123')devolverá 4 en lugar de 5). Si la base de datos utiliza la intercalación 'C', no debería haber ningún cambio en el orden de las cadenas ASCII. Sin embargo, es probable que deba reconstruir cualquier índice que contenga caracteres no ASCII.

Caveat emptor. El volcado y la recarga proporcionan una forma de verificar que el contenido de su base de datos esté realmente en la codificación que espera, y esto no es así. Y si resulta que tenía algunos datos codificados incorrectamente en la base de datos, el rescate será difícil. Entonces, si puede, descargue y reinicialice.

arácnido
fuente
1
+1 Gracias. Mi máquina de desarrollo usa codificación UTF8 pero mi producción usa LATIN1. Tenía muchos errores debido a esto.
Luiz Damim
1
Me está dando este error: -bash: syntax error near unexpected token (''
Abhipso Ghosh
@AbhipsoGhosh no se supone que se pegue en un shell bash, sino en el psqlindicador.
Pierre
14

Volcar una base de datos con una codificación específica e intentar restaurarla en otra base de datos con una codificación diferente podría resultar en corrupción de datos. La codificación de datos debe establecerse ANTES de que se inserten datos en la base de datos.

Verifique esto : al copiar cualquier otra base de datos, la codificación y la configuración regional no se pueden cambiar de las de la base de datos de origen, porque eso podría resultar en datos corruptos.

Y esto : algunas categorías de configuración regional deben tener sus valores fijos cuando se crea la base de datos. Puede usar diferentes configuraciones para diferentes bases de datos, pero una vez que se crea una base de datos, ya no puede cambiarlas para esa base de datos. LC_COLLATE y LC_CTYPE son estas categorías. Afectan el orden de clasificación de los índices, por lo que deben mantenerse fijos o los índices de las columnas de texto se dañarían. ( Pero puede aliviar esta restricción usando intercalaciones, como se discutió en la Sección 22.2. ) Los valores predeterminados para estas categorías se determinan cuando se ejecuta initdb, y esos valores se usan cuando se crean nuevas bases de datos, a menos que se especifique lo contrario en el comando CREATE DATABASE.


Preferiría reconstruir todo desde el principio correctamente con una codificación local correcta en su sistema operativo Debian como se explica aquí :

su root

Reconfigure su configuración local:

dpkg-reconfigure locales

Elija su localidad (como por ejemplo para francés en Suiza: fr_CH.UTF8)

Desinstale y limpie correctamente 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

Vuelva a instalar postgresql:

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

Ahora, cualquier nueva base de datos se creará automáticamente con la codificación correcta, LC_TYPE (clasificación de caracteres) y LC_COLLATE (orden de clasificación de cadenas).

Douglas
fuente
2
Creo que es "dpkg-reconfigure locales", en plural. La forma singular no parece funcionar (solo marcada).
foo
9

La respuesta de Daniel Kutik es correcta, pero puede ser aún más segura con el cambio de nombre de la base de datos .

Entonces, la forma verdaderamente segura es:

  1. Cree una nueva base de datos con diferentes codificaciones y nombres.
  2. Descarga tu base de datos
  3. Restaurar el volcado a la nueva base de datos
  4. Pruebe que su aplicación se ejecute correctamente con la nueva base de datos
  5. Cambie el nombre de la antigua base de datos a algo significativo
  6. Cambiar el nombre de la nueva base de datos
  7. Prueba la aplicación de nuevo
  8. Suelta la base de datos antigua

En caso de emergencia, simplemente cambie el nombre de las bases de datos.

Sergey Zarubin
fuente
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
fuente