Migrar de MySQL a PostgreSQL en Linux (Kubuntu)
-
26-09-2019 - |
Pregunta
Hace mucho tiempo en un sistema muy, muy lejana ...
Tratando de migrar una base de datos de MySQL a PostgreSQL. Toda la documentación He leído cubiertas, con gran detalle, cómo migrar la estructura. He encontrado muy poca documentación sobre la migración de los datos. El esquema tiene 13 tablas (que han migrado con éxito) y 9 GB de datos.
MySQL versión: 5.1.x
versión de PostgreSQL: 8.4.x
Quiero usar el lenguaje de programación R para analizar los datos utilizando SQL seleccionar declaraciones; PostgreSQL tiene PL / I, pero MySQL no tiene nada (por lo que puedo decir).
A New Hope
Crea la ubicación de base de datos (/var
no tiene espacio suficiente; también les gusta tener el número de versión de PostgreSQL todas partes - la actualización se rompería guiones!):
-
sudo mkdir -p /home/postgres/main
-
sudo cp -Rp /var/lib/postgresql/8.4/main /home/postgres
-
sudo chown -R postgres.postgres /home/postgres
-
sudo chmod -R 700 /home/postgres
-
sudo usermod -d /home/postgres/ postgres
Todo bien hasta aquí. A continuación, reinicie el servidor y configurar la base de datos usando estas instrucciones de instalación :
-
sudo apt-get install postgresql pgadmin3
-
sudo /etc/init.d/postgresql-8.4 stop
-
sudo vi /etc/postgresql/8.4/main/postgresql.conf
- Cambiar
data_directory
a/home/postgres/main
-
sudo /etc/init.d/postgresql-8.4 start
-
sudo -u postgres psql postgres
-
\password postgres
-
sudo -u postgres createdb climate
-
pgadmin3
Uso pgadmin3
para configurar la base de datos y crear un esquema.
El episodio continúa en un shell remoto conocido como bash
, con las dos bases de datos de funcionamiento, y la instalación de un conjunto de herramientas con un logotipo bastante inusual: SQL Hada .
-
perl Makefile.PL
-
sudo make install
-
sudo apt-get install perl-doc
(extrañamente, no se llamaperldoc
) -
perldoc SQL::Translator::Manual
Extraer una DDL PostgreSQL ambiente y todos los datos MySQL
:
-
sqlt -f DBI --dsn dbi:mysql:climate --db-user user --db-password password -t PostgreSQL > climate-pg-ddl.sql
- Editar
climate-pg-ddl.sql
y convertir los identificadores a minúsculas, y insertar la referencia esquema (usando VIM):-
:%s/"\([A-Z_]*\)"/\L\1/g
-
:%s/ TABLE / TABLE climate./g
-
:%s/ on / on climate./g
-
-
mysqldump --skip-add-locks --complete-insert --no-create-db --no-create-info --quick --result-file="climate-my.sql" --databases climate --skip-comments -u root -p
Podría ser útil para simplemente cambiar el nombre de las tablas y columnas de MySQL en minúsculas:
-
select concat( 'RENAME TABLE climate.', TABLE_NAME, ' to climate.', lower(TABLE_NAME), ';' ) from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='climate';
- Ejecutar los comandos de la etapa anterior.
- Es probable que haya una manera de hacer lo mismo para las columnas; Les cambiado manualmente porque era más rápido que encontrar la manera de escribir la consulta.
La base de datos Contraataca
recrear la estructura en PostgreSQL como sigue:
-
pgadmin3
(cambia a ella) - Haga clic en el Ejecutar SQL arbitrario consultas icono
- Abrir
climate-pg-ddl.sql
- Busca
TABLE "
reemplazar conTABLE climate."
(insertar el nombre de esquemaclimate
) - Busca
on "
reemplazar conon climate."
(insertar el nombre de esquemaclimate
) - Pulse
F5
para ejecutar
Esto resulta en:
Query returned successfully with no result in 122 ms.
Respuestas de la Jedi
En este punto estoy perplejo.
- ¿Dónde puedo ir desde aquí ( ¿Cuáles son los pasos ) para convertir
climate-my.sql
aclimate-pg.sql
para que puedan ser ejecutadas en PostgreSQL? - ¿Cómo me aseguro de que los índices se copian correctamente (para mantener la integridad de referencia; no tengo limitaciones en el momento de facilitar la transición)?
- ¿Cómo me aseguro que la adición de nuevas filas en PostgreSQL se iniciará la enumeración del índice de la última fila insertada (y no el conflicto con una clave principal existente de la secuencia)?
- ¿Cómo se asegura el nombre de esquema llega a través de la hora de transformar los datos from MySQL a PostgreSQL insertos?
Recursos
Se necesitaba un poco de información para llegar hasta aquí:
- https://help.ubuntu.com/community/PostgreSQL
- http://articles.sitepoint.com/article/site-mysql- postgresql-1
- http://wiki.postgresql.org/wiki/Converting_from_other_Databases_to_PostgreSQL#MySQL
- http://pgfoundry.org/frs/shownotes.php?release_id=810
- http://sqlfairy.sourceforge.net/
Gracias!
Solución
Lo que suelo hacer para este tipo de migraciones es dos veces:
- Extracto de toda la definición de la base de datos MySQL y adaptarlo a la sintaxis de PostgreSQL.
- Ir sobre la definición de base de datos y transformarla para tomar ventaja de la funcionalidad en PostgreSQL que no existe en MySQL.
A continuación, realice la conversión, y escribir un programa en cualquier idioma que se sienta más cómodo que lleva a cabo el siguiente:
- lee los datos de la base de datos MySQL.
- haga que cualquier transformación es necesaria en los datos que se almacenan en la base de datos PostgreSQL.
- Guarda los datos ahora transformadas en la base de datos PostgreSQL.
Volver a diseñar las tablas de PostgreSQL para tomar ventaja de sus características.
Si usted acaba de hacer algo así como el uso de un script sed
para convertir el volcado SQL de un formato a otro, todo lo que está haciendo es poner una base de datos MySQL en un servidor PostgreSQL. Usted puede hacer eso, y todavía habrá algún beneficio de hacerlo, pero si usted va a migrar, migrar por completo.
Esto implicará un tiempo de poco más por adelantado pasó, pero todavía no he encontrado una situación en la que no vale la pena.
Otros consejos
Convertir el archivo a un formato mysqldump PostgreSQL ambiente
Convertir los datos de la siguiente manera (no usar mysql2pgsql.perl ):
-
Escapar de las cotizaciones.
sed "s/\\\'/\'\'/g" climate-my.sql | sed "s/\\\r/\r/g" | sed "s/\\\n/\n/g" > escaped-my.sql
-
Reemplazar el
USE "climate";
con una ruta de búsqueda y comentar los comentarios:sed "s/USE \"climate\";/SET search_path TO climate;/g" escaped-my.sql | sed "s/^\/\*/--/" > climate-pg.sql
-
Conectar a la base de datos.
sudo su - postgres
psql climate
-
establecer la codificación (mysqldump ignora su parámetro de codificación) y a continuación, ejecutar la secuencia de comandos.
\encoding iso-8859-1
\i climate-pg.sql
Esta serie de pasos probablemente no funcionará para bases de datos complejas con muchos tipos mixtos. Sin embargo, funciona para integer
s, varchar
s y float
s.
índices, claves primarias, y secuencias
Desde mysqldump
incluye las claves principales en la generación de las declaraciones INSERT
, lo harán Trump secuencia automática de la tabla. Las secuencias para todas las tablas se mantuvieron 1 después de una inspección.
Establecer la secuencia después de la importación
El uso del comando ALTER SEQUENCE
pondrá asimismo a que cualquier valor que se necesita.
esquema de prefijo
No hay necesidad de prefijar las tablas con el nombre de esquema. Uso:
SET search_path TO climate;
Si has convertido un esquema a continuación, los datos que migran sería la parte fácil:
-
Esquema de volcado de PostgreSQL (que dice que usted tiene esquema convertido a Postgres, por lo que vamos a volcar todo por ahora, ya que vamos a borrar y volver a crear la base de datos de destino, para que lo limpien):
pg_dump dbname > /tmp/dbname-schema.sql
-
dividida esquema a 2 partes -
/tmp/dbname-schema-1.sql
contiene crear declaraciones de mesa,/tmp/dbname-schema-2.sql
- el resto. PostgreSQL tiene que importar datos antes de claves externas, etc. desencadenantes son importados, pero después de las definiciones de tabla son importados. -
base de datos de recrear con sólo 1 parte de esquema:
drop database dbname create database dbname \i /tmp/dbname-schema-1.sql -- now we have tables without data, triggers, foreign keys etc.
-
importar datos:
( echo 'start transaction'; mysqldump --skip-quote-names dbname | grep ^INSERT; echo 'commit' ) | psql dbname -- now we have tables with data, but without triggers, foreign keys etc.
Una opción
--skip-quote-names
se añadió en MySQL 5.1.3, por lo que si usted tiene versión anterior, a continuación, instalar nuevos MySQL temporalmente en/tmp/mysql
(configure --prefix=/tmp/mysql && make install
debe hacer) y el uso/tmp/mysql/bin/mysqldump
. -
importar el resto del esquema:
psql dbname start transaction \i /tmp/dbname-schema-2.sql commit -- we're done
etlalchemy . Permite migrar desde MySQL a PostgreSQL , o entre varias otras bases de datos, en 4 líneas de Python. Puede leer más sobre él aquí .
Para instalar: pip install etlalchemy
Para ejecutar:
from etlalchemy import ETLAlchemySource, ETLAlchemyTarget
# Migrate from MySQL to PostgreSQL
src = ETLAlchemySource("mysql://user:passwd@hostname/dbname")
tgt = ETLAlchemyTarget("postgresql://user:passwd@hostname/dbname",
drop_database=True)
tgt.addSource(src)
tgt.migrate()