Migrar de MySQL a PostgresQL
El problema radica en la diferencia que hay en la sintaxis del lenguaje SQL de ambos, se parecen pero no son iguales, yo creo que lo mas complicado es migrar los campos que están señalados como AUTO_INCREMENT en MySQL, en PostgreSQL no existe AUTO_INCREMENT como atributo de campo, para ello es necesario crear una secuencia y enlazarlo al campo.
Manos a la obra!
Paso 1: Generar un respaldo de la ESTRUCTURA de la base de datos MySQL
- Code: Seleccionar todo
- $mysqldump -u [usuario] -p [base_de_datos] --no-data > [archivo_salida].sql
Donde:
- [usuario] el el nombre de usuario con el que accedemos a la base de datos (usualmente root)
- [base_de_datos] es el nombre de la base de datos que vamos a migrar (en este caso la base de datos de ejemplo World).
- [archivo_salida] es el nombre de nuestro archivo de salida que contendrá los comandos SQL generados por mysqldump
- El parametro -p es para que musqldump nos pregunte por la contraseña del usuario, si no hay contraseña de base de datos entonces obviar este parametro.
- El parametro --no-data omitirá los datos, por que sólo necesitamos la estructura de las tablas, una vez migrada la estructura seguimos con los datos mas adelante.
El comando se vería de la siguiente forma:
- Code: Seleccionar todo
- $mysqldump -u root -p world --no-data > world-mysql.sql
El comando producirá un archivo parecido al siguiente:
- Code: Seleccionar todo
- -- MySQL dump 10.13 Distrib 5.1.54, for debian-linux-gnu (i686)
- --
- -- Host: localhost Database: world
- -- ------------------------------------------------------
- -- Server version 5.1.54-1ubuntu4
- --
- -- Table structure for table `City`
- --
- /*!40101 SET @saved_cs_client = @@character_set_client */;
- /*!40101 SET character_set_client = utf8 */;
- /*!40101 SET character_set_client = @saved_cs_client */;
- --
- -- Table structure for table `Country`
- --
- /*!40101 SET @saved_cs_client = @@character_set_client */;
- /*!40101 SET character_set_client = utf8 */;
- /*!40101 SET character_set_client = @saved_cs_client */;
- --
- -- Table structure for table `CountryLanguage`
- --
- /*!40101 SET @saved_cs_client = @@character_set_client */;
- /*!40101 SET character_set_client = utf8 */;
- /*!40101 SET character_set_client = @saved_cs_client */;
- /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
- -- Dump completed on 2011-09-17 11:36:57
Paso 2: Traducir SQL de MySQL a SQL de PostgresSQL utilizando mysql2pgsql.perl
- Code: Seleccionar todo
- $perl mysql2pgsql.perl [opciones] sql_formato_mysql.sql sql_formato_postgresql.sql
Para nuestro caso, el comando que ejecutamos es:
- Code: Seleccionar todo
- $perl mysql2pgsql.perl --nodrop world-mysql.sql world-postgresql.sql
Donde:
- La opción --nodrop hace que el script no incluya los comandos DROP TABLE antes de crear las tablas.
- Code: Seleccionar todo
- --
- -- Generated from mysql2pgsql.perl
- -- http:// gborg.postgresql.org/project/mysql2psql/
- -- (c) 2001 - 2007 Jose M. Duarte, Joseph Speigle
- --
- -- warnings are printed for drop tables if they do not exist
- -- please see http:// archives.postgresql.org/pgsql-novice/2004-10/msg00158.php
- -- ##############################################################
- -- MySQL dump 10.13 Distrib 5.1.54, for debian-linux-gnu (i686)
- --
- -- Host: localhost Database: world
- -- ------------------------------------------------------
- -- Server version 5.1.54-1ubuntu4
- --
- -- Table structure for table City
- --
- DROP SEQUENCE "city_id_seq" CASCADE ;
- CREATE SEQUENCE "city_id_seq" START WITH 4080 ;
- CREATE TABLE "city" (
- "id" integer DEFAULT nextval('"city_id_seq"') NOT NULL,
- "name" char(35) NOT NULL DEFAULT '',
- "countrycode" char(3) NOT NULL DEFAULT '',
- "district" char(20) NOT NULL DEFAULT '',
- "population" int NOT NULL DEFAULT '0',
- primary key ("id")
- ) ;
- /*!40101 SET character_set_client = @saved_cs_client */;
- /*!40101 SET @saved_cs_client = @@character_set_client */;
- /*!40101 SET character_set_client = utf8 */;
- --
- -- Table structure for table Country
- --
- CREATE TABLE "country" (
- "code" char(3) NOT NULL DEFAULT '',
- "name" char(52) NOT NULL DEFAULT '',
- "continent" varchar CHECK ("continent" IN ( 'Asia','Europe','North America','Africa','Oceania','Antarctica','South America' )) NOT NULL DEFAULT 'Asia',
- "region" char(26) NOT NULL DEFAULT '',
- "surfacearea" double precision NOT NULL DEFAULT '0.00',
- "indepyear" smallint DEFAULT NULL,
- "population" int NOT NULL DEFAULT '0',
- "lifeexpectancy" double precision DEFAULT NULL,
- "gnp" double precision DEFAULT NULL,
- "gnpold" double precision DEFAULT NULL,
- "localname" char(45) NOT NULL DEFAULT '',
- "governmentform" char(45) NOT NULL DEFAULT '',
- "headofstate" char(60) DEFAULT NULL,
- "capital" int DEFAULT NULL,
- "code2" char(2) NOT NULL DEFAULT '',
- primary key ("code")
- ) ;
- /*!40101 SET character_set_client = @saved_cs_client */;
- /*!40101 SET @saved_cs_client = @@character_set_client */;
- /*!40101 SET character_set_client = utf8 */;
- --
- -- Table structure for table CountryLanguage
- --
- CREATE TABLE "countrylanguage" (
- "countrycode" char(3) NOT NULL DEFAULT '',
- "language" char(30) NOT NULL DEFAULT '',
- "isofficial" varchar CHECK ("isofficial" IN ( 'T','F' )) NOT NULL DEFAULT 'F',
- "percentage" double precision NOT NULL DEFAULT '0.0',
- primary key ("countrycode", "language")
- ) ;
Notar el cambio en la forma de declarar los campos y la creación de secuencias. Los comentarios en PostgreSQL son solo eso comentarios.
Paso 3: Volcar la estructura de las tablas a PostgreSQL
- Code: Seleccionar todo
- $su postgres
- createdb world
- psql -f world_postgresql.sql -u usuario-db word
Paso 4: Volcar los datos de MySQL a PostgreSQL
- Code: Seleccionar todo
- $mysqldump -u root -p world --no-create-info --complete-insert --skip-add-locks > world-mysql-data.sql
Donde:
- --no-create-info Omite los scripts de creación de tabla (no las necesitamos)
- --complete-insert Hace que los comandos INSERT contengan también los nombres de las columnas, PostgreSQL no permite comandos INSERT sin los nombres de las columnas.
- --skip-add-locks omite el comando LOCK TABLE ... ese comando también es diferente en PostgreSQL.
- Code: Seleccionar todo
- -- MySQL dump 10.13 Distrib 5.1.54, for debian-linux-gnu (i686)
- --
- -- Host: localhost Database: world
- -- ------------------------------------------------------
- -- Server version 5.1.54-1ubuntu4
- --
- -- Dumping data for table `City`
- --
- (2,'Qandahar','AFG','Qandahar',237500),
- (3,'Herat','AFG','Herat',186800)
- ...
- --
- -- Dumping data for table `Country`
- --
- `Population`, `LifeExpectancy`, `GNP`, `GNPOld`, `LocalName`, `GovernmentForm`,
- `HeadOfState`, `Capital`, `Code2`)
- 'Aruba','Nonmetropolitan Territory of The Netherlands','Beatrix',129,'AW'),
- ('AFG','Afghanistan','Asia','Southern and Central Asia',652090.00,1919,22720000,
- ('AGO','Angola','Africa','Central Africa',1246700.00,1975,12878000,38.3,6648.00,7984.00,
- 'Angola','Republic','José Eduardo dos Santos',56,'AO'),
- 'Anguilla','Dependent Territory of the UK','Elisabeth II',62,'AI'),
- ('ALB','Albania','Europe','Southern Europe',28748.00,1912,3401200,71.6,3205.00,2500.00,
- 'Shqipëria','Republic','Rexhep Mejdani',34,'AL'),
- ...
- --
- -- Dumping data for table `CountryLanguage`
- --
- ('ABW','English','F',9.5),
- ('ABW','Papiamento','F',76.7),
- ('ABW','Spanish','F',7.4)
- ...
- -- Dump completed on 2011-09-18 17:41:21
Es probable que tengas problemas con el caracter `, para ello vamos a reemplazar el caracter con la doble comilla " utilizando:
- Code: Seleccionar todo
- $sed -i 's/`/'"'/g' world-mysql-data.sql
Pueden también utilizar su editor de texto favorito, el resultado es el siguiente:
- Code: Seleccionar todo
- -- MySQL dump 10.13 Distrib 5.1.54, for debian-linux-gnu (i686)
- --
- -- Host: localhost Database: world
- -- ------------------------------------------------------
- -- Server version 5.1.54-1ubuntu4
- --
- -- Dumping data for table "City"
- --
- INSERT INTO "City" ("ID", "Name", "CountryCode", "District", "Population")
- VALUES (1,'Kabul','AFG','Kabol',1780000),
- (2,'Qandahar','AFG','Qandahar',237500),
- (3,'Herat','AFG','Herat',186800)
- ...
- --
- -- Dumping data for table "Country"
- --
- INSERT INTO "Country" ( "Code", "Name", "Continent", "Region", "SurfaceArea", "IndepYear",
- "Population", "LifeExpectancy", "GNP", "GNPOld", "LocalName", "GovernmentForm",
- "HeadOfState", "Capital", "Code2")
- VALUES ('ABW','Aruba','North America','Caribbean',193.00,NULL,103000,78.4,828.00,793.00,
- 'Aruba','Nonmetropolitan Territory of The Netherlands','Beatrix',129,'AW'),
- ('AFG','Afghanistan','Asia','Southern and Central Asia',652090.00,1919,22720000,
- 45.9,5976.00,NULL,'Afganistan/Afqanestan','Islamic Emirate','Mohammad Omar',1,'AF'),
- ('AGO','Angola','Africa','Central Africa',1246700.00,1975,12878000,38.3,6648.00,7984.00,
- 'Angola','Republic','José Eduardo dos Santos',56,'AO'),
- ('AIA','Anguilla','North America','Caribbean',96.00,NULL,8000,76.1,63.20,NULL,
- 'Anguilla','Dependent Territory of the UK','Elisabeth II',62,'AI'),
- ('ALB','Albania','Europe','Southern Europe',28748.00,1912,3401200,71.6,3205.00,2500.00,
- 'Shqipëria','Republic','Rexhep Mejdani',34,'AL'),
- ...
- --
- -- Dumping data for table "CountryLanguage"
- --
- INSERT INTO "CountryLanguage" ("CountryCode", "Language", "IsOfficial", "Percentage")
- VALUES ('ABW','Dutch','T',5.3),
- ('ABW','English','F',9.5),
- ('ABW','Papiamento','F',76.7),
- ('ABW','Spanish','F',7.4)
- ...
- -- Dump completed on 2011-09-18 17:41:21
Una vez listo el archivo que contiene los datos, los volcamos a PostgreSQL, al igual que el paso 3:
- Code: Seleccionar todo
- $su postgres
- psql -f world_mysql-data.sql -u usuario-db word
Enjoy, es todo!
Tags: bases de datos
Otros Artículos en esta sección
-
Si tienes algo interesante que decir puedes publicar artículos en nuestro sitio web. Las instrucciones son fáciles.Deseas saber como convertir un numero decimal a binario? esta es una implementacion en varios lenguajes de programación. PHP, C++, VB.NET, C#, JAVA, DELPHI, TCL, ASP.NET, etcSi necesitas mantener un inventario en tiempo real de los equipos conectados a tu red, te mostramos paso a paso como instalar y utilizar OCS Inventory.¿Alguna duda? Sientete libre de hacer tus pruntas en nuestro:

foro de Programación »
