Convierte una base de datos en otra base de datos
Suelta un volcado de mysqldump, mariadb-dump, pg_dump, SSMS, SQL Developer o SQLcl, o un archivo .db de SQLite, y descarga un script para PostgreSQL, MySQL, MariaDB, SQLite, SQL Server u Oracle con las mismas tablas, claves, índices y datos. Cada cambio aparece en un informe, y el volcado nunca sale de tu computadora.
18 filas convertidas, 8 correcciones, ninguna rechazada
Tablas en shop_2024.sqlVolcado de MySQL 8.0.46 · escrito por mysqldump · utf8mb4
customers8 filas3
7 columnas id bigint not null name varchar(100) not null email varchar(150) not null country varchar(2) not null is_active boolean not null signed_up date created_at timestamptz(0) not null orders10 filas5
9 columnas id bigint not null customer_id bigint not null status text not null total numeric(10,2) not null items integer not null ordered_at timestamp(0) not null shipped_at timestamp(0) note varchar(255) updated_at timestamptz(0) not null
-- Written by IntoSQL from a MySQL dump. Load it with: psql -v ON_ERROR_STOP=1 -f <file>
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET synchronous_commit = off;
SET maintenance_work_mem = '512MB';
CREATE TABLE customers (
id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL,
name varchar(100) NOT NULL,
email varchar(150) NOT NULL,
country varchar(2) DEFAULT 'US' NOT NULL,
is_active boolean DEFAULT true NOT NULL,
signed_up date,
created_at timestamptz(0) DEFAULT CURRENT_TIMESTAMP NOT NULL,
CONSTRAINT customers_id_check CHECK (id >= 0)
);
CREATE TABLE orders (
id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL,
customer_id bigint NOT NULL,
status text DEFAULT 'pending' NOT NULL,
total numeric(10,2) NOT NULL,
items integer DEFAULT 1 NOT NULL,
ordered_at timestamp(0) NOT NULL,
shipped_at timestamp(0),
note varchar(255),
updated_at timestamptz(0) DEFAULT CURRENT_TIMESTAMP NOT NULL,
CONSTRAINT orders_id_check CHECK (id >= 0),
CONSTRAINT orders_customer_id_check CHECK (customer_id >= 0),
CONSTRAINT orders_status_check CHECK (status IN ('pending', 'paid', 'shipped', 'cancelled', '')),
CONSTRAINT orders_items_check CHECK (items >= 0)
);
COPY customers (id, name, email, country, is_active, signed_up, created_at) FROM stdin;
1 Ana Martínez ana@example.com MX t 2023-01-15 2023-01-15 10:24:00+00:00
2 Zoë Müller zoe@example.de DE t 2023-02-03 2023-02-03 08:11:42+00:00
3 José Peña jose@example.es ES f 2023-03-21 2023-03-21 19:05:17+00:00
4 李雷 lilei@example.cn CN t 2023-05-09 2023-05-09 02:40:00+00:00
5 Noah O'Brien noah@example.ie IE t \N 2023-06-30 14:00:00+00:00
6 Amélie Laurent amelie@example.fr FR t 2024-01-02 2024-01-02 09:30:00+00:00
7 Ravi Patel ravi@example.in IN f 2024-02-29 2024-02-29 23:59:59+00:00
8 Sofia Rossi 🌻 sofia@example.it IT t 2024-04-12 2024-04-12 12:12:12+00:00
\.
COPY orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, updated_at) FROM stdin;
1 1 shipped 129.90 3 2024-03-01 10:00:00 2024-03-02 16:30:00 \N 2024-03-02 16:30:00+00:00
2 2 paid 54.00 1 2024-03-02 11:15:00 \N Gift wrap 🎁 2024-03-02 11:20:00+00:00
3 1 cancelled 12.50 1 2024-03-03 09:45:00 \N Customer changed their mind 2024-03-03 10:00:00+00:00
4 4 shipped 980.00 12 2024-03-05 02:10:00 2024-03-07 08:00:00 请小心轻放 2024-03-07 08:00:00+00:00
5 5 pending 45.75 2 2024-03-08 17:20:00 \N Leave at the door; ring twice 2024-03-08 17:20:00+00:00
6 6 shipped 310.40 5 2024-03-10 13:00:00 2024-03-11 09:00:00 Fragile: "glass" 2024-03-11 09:00:00+00:00
7 8 paid 76.20 2 2024-03-11 18:45:00 \N \N 2024-03-11 18:46:00+00:00
8 2 19.99 1 2024-03-12 08:00:00 \N Status lost in an old import 2024-03-12 08:00:00+00:00
9 3 shipped 64.00 2 2024-03-14 15:30:00 \N Shipping date never recorded 2024-03-15 10:00:00+00:00
10 7 paid 1499.00 1 2024-03-15 21:05:00 \N C:\\Users\\ravi\\invoice.pdf 2024-03-15 21:05:00+00:00
\.
-- Keys, indexes and constraints, after the rows so each builds once.
CREATE UNIQUE INDEX customers_pkey ON customers (id);
CREATE UNIQUE INDEX customers_uq_email ON customers (email);
CREATE UNIQUE INDEX orders_pkey ON orders (id);
CREATE INDEX orders_idx_customer ON orders (customer_id);
CREATE INDEX orders_idx_status_date ON orders (status, ordered_at);
ALTER TABLE customers ADD CONSTRAINT customers_pkey PRIMARY KEY USING INDEX customers_pkey;
ALTER TABLE customers ADD CONSTRAINT customers_uq_email UNIQUE USING INDEX customers_uq_email;
ALTER TABLE orders ADD CONSTRAINT orders_pkey PRIMARY KEY USING INDEX orders_pkey;
ALTER TABLE orders ADD CONSTRAINT fk_orders_customer FOREIGN KEY (customer_id) REFERENCES customers (id) NOT VALID;
DO $f$ BEGIN
ALTER TABLE orders VALIDATE CONSTRAINT fk_orders_customer;
EXCEPTION WHEN foreign_key_violation THEN
RAISE WARNING 'foreign key % has rows without a parent: it stays NOT VALID, and new rows are checked', 'fk_orders_customer';
END $f$;
SELECT setval(pg_get_serial_sequence('customers', 'id'), LEAST(GREATEST(COALESCE((SELECT max(id) FROM customers)::numeric, 0) + 1, 1001), 9223372036854775807)::bigint, false);
COMMENT ON TABLE customers IS 'People who bought at least once';
SELECT setval(pg_get_serial_sequence('orders', 'id'), LEAST(GREATEST(COALESCE((SELECT max(id) FROM orders)::numeric, 0) + 1, 5001), 9223372036854775807)::bigint, false);
CREATE FUNCTION orders_updated_at_on_update() RETURNS trigger LANGUAGE plpgsql AS $f$
BEGIN
IF NEW IS DISTINCT FROM OLD AND NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at THEN
NEW.updated_at := CURRENT_TIMESTAMP;
END IF;
RETURN NEW;
END
$f$;
CREATE TRIGGER orders_updated_at_on_update BEFORE UPDATE ON orders FOR EACH ROW EXECUTE FUNCTION orders_updated_at_on_update();
Correcciones
- "id" de customers no tiene signo, así que se volvió bigint con un CHECK de que no sea negativa.
- "signed_up" de customers ahora admite NULL: algunos de sus valores no se pudieron guardar y quedan en NULL.
- El valor predeterminado de "signed_up" en customers, 0000‑00‑00, no es una fecha que PostgreSQL acepte, así que la columna no tiene valor predeterminado.
- "customer_id" de orders no tiene signo, así que se volvió bigint con un CHECK de que no sea negativa.
- "id" de orders no tiene signo, así que se volvió bigint con un CHECK de que no sea negativa.
- "items" de orders no tiene signo, así que se volvió integer con un CHECK de que no sea negativa.
- 1 fila de "status" en orders contiene el valor vacío que MySQL guarda para entradas no válidas; el CHECK de sus valores lo admite.
- "updated_at" de orders cambia a la hora actual en cada actualización; en PostgreSQL lo hace un disparador.
Para revisar
- 1 valor en "signed_up" de customers es una fecha cero o imposible, como 0000‑00‑00, que PostgreSQL no puede guardar, así que queda en NULL. Si esas fechas significan algo, reemplázalas en el origen por fechas reales antes del volcado.
- 1 valor en "shipped_at" de orders es una fecha cero o imposible, como 0000‑00‑00 00:00:00, que PostgreSQL no puede guardar, así que queda en NULL. Si esas fechas significan algo, reemplázalas en el origen por fechas reales antes del volcado.
Tu archivo se convierte en esta computadora y nunca se sube.
Otros ejemplos:
Todos los pares de bases de datos
Las filas son la base de datos de la que viene el volcado, las columnas la base de datos para la que es el script. Cada par tiene su propia página con el convertidor preparado para él, las reglas que aplica y cómo cargar el script.
- MySQL
- MariaDB
- PostgreSQL
- SQL Server
- SQLite
- Oracle
| de ↓ a → | PostgreSQL | MySQL | MariaDB | SQLite | SQL Server | Oracle |
|---|---|---|---|---|---|---|
| MySQL | MySQL a PostgreSQL | MySQL a MySQL | MySQL a MariaDB | MySQL a SQLite | MySQL a SQL Server | MySQL a Oracle |
| MariaDB | MariaDB a PostgreSQL | MariaDB a MySQL | MariaDB a MariaDB | MariaDB a SQLite | MariaDB a SQL Server | MariaDB a Oracle |
| PostgreSQL | PostgreSQL a PostgreSQL | PostgreSQL a MySQL | PostgreSQL a MariaDB | PostgreSQL a SQLite | PostgreSQL a SQL Server | PostgreSQL a Oracle |
| SQL Server | SQL Server a PostgreSQL | SQL Server a MySQL | SQL Server a MariaDB | SQL Server a SQLite | SQL Server a SQL Server | SQL Server a Oracle |
| SQLite | SQLite a PostgreSQL | SQLite a MySQL | SQLite a MariaDB | SQLite a SQLite | SQLite a SQL Server | SQLite a Oracle |
| Oracle | Oracle a PostgreSQL | Oracle a MySQL | Oracle a MariaDB | Oracle a SQLite | Oracle a SQL Server | Oracle a Oracle |
Qué se conserva y qué se informa
El convertidor lee el propio volcado, sin un servidor de base de datos, y escribe el script a partir de lo que contiene. La página de cada par lista las reglas que aplica, entre 25 y 67 por par, con la línea del informe que escribe cada una.
Se conserva en el script
- Tablas y columnas, cada una con el tipo más cercano que tiene el destino, con su longitud y precisión.
- Claves primarias, únicas y foráneas, índices y valores por defecto.
- Columnas AUTO_INCREMENT, de identidad y serial, con el id de cada fila y el contador siguiendo donde lo dejó el volcado.
- Cada fila, con fechas, decimales, texto y valores binarios tal como los guarda el volcado.
Aparece en el informe
- Valores que el destino no admite tal cual, como una fecha 0000-00-00 en PostgreSQL, con la columna y cuántos hay.
invalid_date_null - Tipos que el destino no tiene, como ENUM o INET6, con el tipo en que se convirtió cada uno.
type_replaced - Vistas, disparadores, procedimientos, funciones y eventos, por nombre: se escriben en el propio lenguaje de cada base de datos, así que no se convierten.
not_converted_objects - Texto que no es válido en su juego de caracteres, y volcados que ya perdieron sus caracteres de 4 bytes.
invalid_utf8_replaced
Comparado con pgloader
Los mismos volcados, convertidos y cargados por IntoSQL y por pgloader 3.6.7 en una sola máquina (un i9-10900K de 10 núcleos con un SATA SSD), en octubre de 2026.
- Una columna TINYINT(1) con 2, -1 y -5: pgloader carga true en cada una, sin advertencia. IntoSQL conserva los números y el informe dice por qué.
- Un volcado con un valor predeterminado 'it's', una tabla con una comilla invertida en el nombre, un ENUM con el valor vacío y un TIME de más de 24 horas: pgloader se detiene. IntoSQL lo convierte y lo carga.
- Lo que carga pgloader pierde sus claves primarias, únicas y foráneas, y sus identidades. IntoSQL las conserva todas.
- Un volcado de 5.3 GB con 30 millones de filas: pgloader necesita restaurarlo antes en un MySQL en ejecución, lo que tarda 18 minutos, y luego se queda sin memoria con su configuración predeterminada. IntoSQL convierte el volcado en 10 segundos, y psql carga el script en unos 3 minutos.
- En 476 volcados de MySQL 5.5 a 9 y MariaDB 10.3 a 12, cargados en PostgreSQL 13 y 18: ningún error de carga, y ningún valor cambió sin una línea en el informe.
Exporta la base de datos que tienes
El convertidor lee un archivo, no un servidor en ejecución. Cada base de datos escribe uno con sus propias herramientas:
MySQL
Un volcado de mysqldump, mysqlpump, phpMyAdmin o Adminer, como .sql o .sql.gz. --default-character-set=utf8mb4 --hex-blob --routines --triggers --events conservan lo más posible.
Guía de migración de MySQL a PostgreSQLMariaDB
Un volcado de mariadb-dump, mysqldump, phpMyAdmin o Adminer, como .sql o .sql.gz, con las mismas opciones que MySQL.
Guía de migración de MariaDB a PostgreSQLPostgreSQL
Un volcado plano de pg_dump o pg_dumpall. Un archivo personalizado (-Fc) se vuelve uno con pg_restore -f dump.sql, sin servidor.
Guía de migración de PostgreSQL a MySQLSQL Server
El script que escribe Generate Scripts de SSMS, con Types of data to script en Schema and data. dbatools y mssql-scripter escriben lo mismo.
Guía de migración de SQL Server a PostgreSQLSQLite
El propio archivo de la base de datos (.db, .sqlite, .sqlite3), o el SQL que escribe sqlite3 app.db .dump.
Guía de migración de SQLite a PostgreSQLOracle
El archivo .sql que escribe Database Export de SQL Developer o SQLcl, con DDL e Insert. Un archivo .dmp de exp o expdp primero tiene que importarse y exportarse de nuevo.
Guía de migración de Oracle a PostgreSQL
Preguntas sobre la migración de bases de datos
¿No encuentras la respuesta? Escríbenos desde la página de contacto y te responde una persona. Página de contacto
¿Se sube mi volcado?
No. El convertidor se ejecuta en tu navegador y lee el volcado de tu disco por partes, así que nunca sale de tu computadora. La app de escritorio y la línea de comandos también convierten en tu computadora.
¿Qué tan grande puede ser el volcado?
El convertidor nunca tiene todo el volcado en memoria: lee el archivo dos veces, por rangos, y escribe el script sobre la marcha. Los volcados de varios gigabytes se convierten en el navegador, en la app de escritorio y con la línea de comandos.
¿De qué versiones puede venir el volcado?
MySQL 5.5 a 9, MariaDB 10.3 a 12, PostgreSQL 10 y posteriores, SQL Server 2017 y posteriores, SQLite 3.0 y posteriores, y Oracle 11g y posteriores. La página de cada par dice en qué versiones carga su script.
¿Necesito un servidor de base de datos en ejecución?
No. El convertidor lee el propio archivo del volcado, así que la base de datos de origen no tiene que correr en ningún lado. El script se carga con el cliente propio del destino, como psql, mysql o sqlcmd.
¿Qué no se convierte?
Las vistas, disparadores, procedimientos almacenados, funciones y eventos se escriben en el propio lenguaje de cada base de datos, así que aparecen en el informe por nombre. Las tablas, claves, índices y filas están todos en el script.
¿Puede cargar el script directo en mi base de datos?
La app de escritorio y el comando intosql load escriben directo en SQLite gratis, y en PostgreSQL, MySQL y MariaDB con IntoSQL Pro. Para SQL Server y Oracle, ejecuta el script con sqlcmd o sqlplus.