Converta um banco de dados em outro banco de dados
Solte um dump do mysqldump, mariadb-dump, pg_dump, SSMS, SQL Developer ou SQLcl, ou um arquivo .db do SQLite, e baixe um script para PostgreSQL, MySQL, MariaDB, SQLite, SQL Server ou Oracle com as mesmas tabelas, chaves, índices e dados. Cada mudança é listada em um relatório, e o dump nunca sai do seu computador.
18 linhas convertidas, 8 correções, nenhuma rejeitada
Tabelas em shop_2024.sqlDump do MySQL 8.0.46 · gerado por mysqldump · utf8mb4
customers8 linhas3
7 colunas 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 linhas5
9 colunas 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();
Correções
- "id" de customers é sem sinal, então virou bigint com um CHECK de que não é negativa.
- "signed_up" de customers agora aceita NULL: alguns dos seus valores não puderam ser guardados e são NULL.
- O valor padrão de "signed_up" em customers, 0000‑00‑00, não é uma data que o PostgreSQL aceite, então a coluna fica sem valor padrão.
- "customer_id" de orders é sem sinal, então virou bigint com um CHECK de que não é negativa.
- "id" de orders é sem sinal, então virou bigint com um CHECK de que não é negativa.
- "items" de orders é sem sinal, então virou integer com um CHECK de que não é negativa.
- 1 linha de "status" em orders contém o valor vazio que o MySQL guarda para entradas inválidas; o CHECK dos valores o permite.
- "updated_at" de orders muda para a hora atual a cada atualização; no PostgreSQL, um gatilho faz isso.
Para revisar
- 1 valor em "signed_up" de customers é uma data zero ou impossível, como 0000‑00‑00, que o PostgreSQL não consegue guardar, então ficou NULL. Se essas datas têm significado, troque-as na origem por datas reais antes do dump.
- 1 valor em "shipped_at" de orders é uma data zero ou impossível, como 0000‑00‑00 00:00:00, que o PostgreSQL não consegue guardar, então ficou NULL. Se essas datas têm significado, troque-as na origem por datas reais antes do dump.
Seu arquivo é convertido neste computador e nunca é enviado.
Outros exemplos:
Todos os pares de bancos de dados
As linhas são o banco de dados de onde vem o dump, as colunas o banco de dados para o qual é o script. Cada par tem sua própria página com o conversor preparado para ele, as regras que aplica e como carregar o script.
- MySQL
- MariaDB
- PostgreSQL
- SQL Server
- SQLite
- Oracle
| de ↓ para → | PostgreSQL | MySQL | MariaDB | SQLite | SQL Server | Oracle |
|---|---|---|---|---|---|---|
| MySQL | MySQL para PostgreSQL | MySQL para MySQL | MySQL para MariaDB | MySQL para SQLite | MySQL para SQL Server | MySQL para Oracle |
| MariaDB | MariaDB para PostgreSQL | MariaDB para MySQL | MariaDB para MariaDB | MariaDB para SQLite | MariaDB para SQL Server | MariaDB para Oracle |
| PostgreSQL | PostgreSQL para PostgreSQL | PostgreSQL para MySQL | PostgreSQL para MariaDB | PostgreSQL para SQLite | PostgreSQL para SQL Server | PostgreSQL para Oracle |
| SQL Server | SQL Server para PostgreSQL | SQL Server para MySQL | SQL Server para MariaDB | SQL Server para SQLite | SQL Server para SQL Server | SQL Server para Oracle |
| SQLite | SQLite para PostgreSQL | SQLite para MySQL | SQLite para MariaDB | SQLite para SQLite | SQLite para SQL Server | SQLite para Oracle |
| Oracle | Oracle para PostgreSQL | Oracle para MySQL | Oracle para MariaDB | Oracle para SQLite | Oracle para SQL Server | Oracle para Oracle |
O que é mantido e o que é relatado
O conversor lê o próprio dump, sem um servidor de banco de dados, e escreve o script a partir do que ele contém. A página de cada par lista as regras que aplica, entre 25 e 67 por par, com a linha do relatório que cada uma escreve.
Mantido no script
- Tabelas e colunas, cada uma com o tipo mais próximo que o destino tem, com seu tamanho e precisão.
- Chaves primárias, únicas e estrangeiras, índices e valores padrão.
- Colunas AUTO_INCREMENT, identity e serial, com o id de cada linha e o contador continuando de onde o dump parou.
- Cada linha, com datas, decimais, texto e valores binários como o dump os guarda.
Listado no relatório
- Valores que o destino não aceita como estão, como uma data 0000-00-00 no PostgreSQL, com a coluna e quantos são.
invalid_date_null - Tipos que o destino não tem, como ENUM ou INET6, com o tipo em que cada um se tornou.
type_replaced - Views, triggers, procedures, funções e eventos, pelo nome: são escritos na própria linguagem de cada banco de dados, então não são convertidos.
not_converted_objects - Texto que não é válido no seu conjunto de caracteres, e dumps que já perderam seus caracteres de 4 bytes.
invalid_utf8_replaced
Comparado com o pgloader
Os mesmos dumps, convertidos e carregados pelo IntoSQL e pelo pgloader 3.6.7 em uma única máquina (um i9-10900K de 10 núcleos com SATA SSD), em outubro de 2026.
- Uma coluna TINYINT(1) com 2, -1 e -5: o pgloader carrega true para cada um, sem aviso. O IntoSQL mantém os números e o relatório explica o motivo.
- Um dump com um valor padrão 'it's', uma tabela com crase no nome, um ENUM com o valor vazio e um TIME acima de 24 horas: o pgloader para. O IntoSQL o converte e o carrega.
- O que o pgloader carrega perdeu as chaves primárias, únicas e estrangeiras e as colunas identity. O IntoSQL mantém todas.
- Um dump de 5.3 GB com 30 milhões de linhas: o pgloader exige restaurá-lo antes em um MySQL em execução, o que leva 18 minutos, e depois fica sem memória com as configurações padrão. O IntoSQL converte o dump em 10 segundos, e o psql carrega o script em cerca de 3 minutos.
- Em 476 dumps do MySQL 5.5 ao 9 e do MariaDB 10.3 ao 12, carregados no PostgreSQL 13 e 18: nenhum erro de carga e nenhum valor alterado sem uma linha no relatório.
Exporte o banco de dados que você tem
O conversor lê um arquivo, não um servidor rodando. Cada banco de dados escreve um com suas próprias ferramentas:
MySQL
Um dump do mysqldump, mysqlpump, phpMyAdmin ou Adminer, como .sql ou .sql.gz. --default-character-set=utf8mb4 --hex-blob --routines --triggers --events mantêm o máximo.
Guia de migração de MySQL para PostgreSQLMariaDB
Um dump do mariadb-dump, mysqldump, phpMyAdmin ou Adminer, como .sql ou .sql.gz, com as mesmas opções do MySQL.
Guia de migração de MariaDB para PostgreSQLPostgreSQL
Um dump simples do pg_dump ou pg_dumpall. Um arquivo custom (-Fc) vira um com pg_restore -f dump.sql, sem servidor.
Guia de migração de PostgreSQL para MySQLSQL Server
O script que o Generate Scripts do SSMS escreve, com Types of data to script em Schema and data. dbatools e mssql-scripter escrevem o mesmo.
Guia de migração de SQL Server para PostgreSQLSQLite
O próprio arquivo do banco de dados (.db, .sqlite, .sqlite3), ou o SQL que sqlite3 app.db .dump escreve.
Guia de migração de SQLite para PostgreSQLOracle
O arquivo .sql que o Database Export do SQL Developer ou o SQLcl escreve, com DDL e Insert. Um arquivo .dmp do exp ou expdp precisa ser importado e exportado de novo antes.
Guia de migração de Oracle para PostgreSQL
Perguntas sobre migração de banco de dados
Não encontrou a resposta? Escreva para nós pela página de contato e uma pessoa responde. Página de contato
Meu dump é enviado?
Não. O conversor roda no seu navegador e lê o dump do seu disco em partes, então ele nunca sai do seu computador. O app para desktop e a linha de comando também convertem no seu computador.
Qual o tamanho máximo do dump?
O conversor nunca guarda o dump inteiro na memória: ele lê o arquivo duas vezes, por intervalos, e escreve o script à medida que avança. Dumps de vários gigabytes são convertidos no navegador, no app para desktop e com a linha de comando.
De quais versões o dump pode vir?
MySQL 5.5 ao 9, MariaDB 10.3 ao 12, PostgreSQL 10 ou posterior, SQL Server 2017 ou posterior, SQLite 3.0 ou posterior, e Oracle 11g ou posterior. A página de cada par diz em quais versões seu script carrega.
Preciso de um servidor de banco de dados rodando?
Não. O conversor lê o próprio arquivo de dump, então o banco de dados de origem não precisa rodar em lugar nenhum. O script carrega com o cliente do próprio destino, como psql, mysql ou sqlcmd.
O que não é convertido?
Views, triggers, stored procedures, funções e eventos são escritos na própria linguagem de cada banco de dados, então aparecem no relatório pelo nome. As tabelas, chaves, índices e linhas estão todos no script.
Ele pode carregar o script direto no meu banco de dados?
O app para desktop e o comando intosql load escrevem direto no SQLite de graça, e no PostgreSQL, MySQL e MariaDB com o IntoSQL Pro. Para SQL Server e Oracle, rode o script com sqlcmd ou sqlplus.