Leve um dump do PostgreSQL para um PostgreSQL mais antigo ou mais novo
Solte um dump simples do pg_dump ou pg_dumpall, como .sql ou .sql.gz, e baixe um script que carrega no PostgreSQL 13 ao 18, seja qual for a versão que escreveu o dump. Identities, enums, arrays e jsonb ficam como estão, tipos trazidos por uma extensão viram texto, e cada mudança é listada no relatório.
18 linhas convertidas, nenhuma correção, nenhuma rejeitada
Tabelas em shop_2024_postgres.sqlDump do PostgreSQL 18.6 · gerado por pg_dump · utf8mb4
customers8 linhas
8 colunas id integer not null name text not null email text not null country varchar(2) not null is_active boolean not null tags text[] not null signed_up date created_at timestamptz(6) not null orders10 linhas
10 colunas id integer not null customer_id integer not null status order_status not null total numeric(10,2) not null items smallint not null ordered_at timestamp(6) not null shipped_at timestamp(6) note text details jsonb delivery interval
Não convertidos
- Visão paid_orders
Cada banco de dados escreve estes objetos na sua própria linguagem. Reescreva-os para o PostgreSQL.
-- Written by IntoSQL from a PostgreSQL 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 TYPE order_status AS ENUM ('pending', 'paid', 'shipped', 'cancelled');
CREATE TABLE customers (
id integer GENERATED BY DEFAULT AS IDENTITY NOT NULL,
name text NOT NULL,
email text NOT NULL,
country varchar(2) DEFAULT 'US' NOT NULL,
is_active boolean DEFAULT true NOT NULL,
tags text[] DEFAULT '{}' NOT NULL,
signed_up date,
created_at timestamptz(6) DEFAULT CURRENT_TIMESTAMP NOT NULL
);
CREATE TABLE orders (
id integer GENERATED BY DEFAULT AS IDENTITY NOT NULL,
customer_id integer NOT NULL,
status order_status DEFAULT 'pending' NOT NULL,
total numeric(10,2) NOT NULL,
items smallint DEFAULT 1 NOT NULL,
ordered_at timestamp(6) NOT NULL,
shipped_at timestamp(6),
note text,
details jsonb,
delivery interval,
CONSTRAINT orders_total_check CHECK (total >= (0))
);
COPY customers (id, name, email, country, is_active, tags, signed_up, created_at) FROM stdin;
1 Ana Martínez ana@example.com MX t {vip} 2023-01-15 2023-01-15 10:24:00+00
2 Zoë Müller zoe@example.de DE t {} 2023-02-03 2023-02-03 08:11:42+00
3 José Peña jose@example.es ES f {wholesale,"late payer"} 2023-03-21 2023-03-21 19:05:17+00
4 李雷 lilei@example.cn CN t {} 2023-05-09 2023-05-09 02:40:00+00
5 Noah O'Brien noah@example.ie IE t {} \N 2023-06-30 14:00:00+00
6 Amélie Laurent amelie@example.fr FR t {vip} 2024-01-02 2024-01-02 09:30:00+00
7 Ravi Patel ravi@example.in IN f {} 2024-02-29 2024-02-29 23:59:59+00
8 Sofia Rossi 🌻 sofia@example.it IT t {} 2024-04-12 2024-04-12 12:12:12+00
\.
COPY orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, details, delivery) FROM stdin;
1 1 shipped 129.90 3 2024-03-01 10:00:00 2024-03-02 16:30:00 \N {"gift": false} 1 day 06:30:00
2 2 paid 54.00 1 2024-03-02 11:15:00 \N Gift wrap 🎁 {"gift": true, "wrap": "red"} \N
3 1 cancelled 12.50 1 2024-03-03 09:45:00 \N Customer changed their mind \N \N
4 4 shipped 980.00 12 2024-03-05 02:10:00 2024-03-07 08:00:00 请小心轻放 {"fragile": true} 2 days 05:50:00
5 5 pending 45.75 2 2024-03-08 17:20:00 \N Leave at the door; ring twice \N \N
6 6 shipped 310.40 5 2024-03-10 13:00:00 2024-03-11 09:00:00 Fragile: "glass" {"fragile": true} 20:00:00
7 8 paid 76.20 2 2024-03-11 18:45:00 \N \N \N \N
8 2 shipped 19.99 1 2024-03-12 08:00:00 infinity Shipped date set to infinity by an old import \N \N
9 3 shipped 64.00 2 2024-03-14 15:30:00 2024-03-15 10:00:00 Two parcels {"parcels": [1, 2]} 18:30:00
10 7 paid 1499.00 1 2024-03-15 21:05:00 \N C:\\Users\\ravi\\invoice.pdf \N \N
\.
-- Keys, indexes and constraints, after the rows so each builds once.
CREATE UNIQUE INDEX customers_email_key ON customers (email);
CREATE UNIQUE INDEX customers_pkey ON customers (id);
CREATE UNIQUE INDEX orders_pkey ON orders (id);
CREATE INDEX idx_orders_customer ON orders (customer_id);
CREATE INDEX idx_orders_status_date ON orders (status, ordered_at);
ALTER TABLE customers ADD CONSTRAINT customers_email_key UNIQUE USING INDEX customers_email_key;
ALTER TABLE customers ADD CONSTRAINT customers_pkey PRIMARY KEY USING INDEX customers_pkey;
ALTER TABLE orders ADD CONSTRAINT orders_pkey PRIMARY KEY USING INDEX orders_pkey;
ALTER TABLE orders ADD CONSTRAINT orders_customer_id_fkey FOREIGN KEY (customer_id) REFERENCES customers (id) NOT VALID;
DO $f$ BEGIN
ALTER TABLE orders VALIDATE CONSTRAINT orders_customer_id_fkey;
EXCEPTION WHEN foreign_key_violation THEN
RAISE WARNING 'foreign key % has rows without a parent: it stays NOT VALID, and new rows are checked', 'orders_customer_id_fkey';
END $f$;
SELECT setval(pg_get_serial_sequence('customers', 'id'), LEAST(GREATEST(COALESCE((SELECT max(id) FROM customers)::numeric, 0) + 1, 1001), 2147483647)::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), 2147483647)::bigint, false);
Correções
Nada precisou de correção.
Para revisar
- 1 visão, gatilho, rotina ou evento não foi convertido; o relatório lista cada um. Recrie-os manualmente no PostgreSQL.
- O índice idx_orders_details de orders usa uma expressão que não pode ser escrita para o PostgreSQL (a gin index), então não é criado. Crie o índice manualmente se as consultas precisarem dele.
Seu arquivo é convertido neste computador e nunca é enviado.
Outros exemplos:
O que muda entre o arquivo e o script
Cada linha é uma regra que o conversor aplica, com a linha do relatório que ele escreve quando a regra muda algo nos seus dados.
varchar(n), char(n), text
os mesmos tipos
Os mesmos tipos, com os mesmos tamanhos.
numeric(p,s), numeric without a precision, NaN and Infinity
os mesmos tipos e valores
O mesmo tipo: cada dígito é copiado como o dump o escreveu.
money
numeric(19,2)
Como money é escrito depende do lc_monetary do servidor, então o valor fica como número sem o símbolo de moeda e carrega com qualquer localidade do destino.
Linha do relatório: type_replaced
enum types
os mesmos tipos enum, criados antes das tabelas
Os rótulos mantêm sua ordem.
enum columns holding values outside their labels
text sem CHECK
O tipo rejeitaria esses valores, então a coluna é text e mantém todos eles.
Linha do relatório: enum_check_skipped
composite and range types the dump defines, extension types (citext, hstore, ltree, PostGIS) and multiranges
text com o texto do PostgreSQL
O script não cria extensões nem tipos compostos, então cada valor mantém o texto que o PostgreSQL escreveu; crie o tipo e altere a coluna depois da carga.
Linha do relatório: type_replaced
citext
text, comparado de forma exata
O script não cria a extensão citext, então essas colunas comparam texto de forma exata; crie-a e volte as colunas depois da carga.
Linha do relatório: case_insensitive_collation
json, jsonb
os mesmos tipos
json mantém o texto como foi escrito; jsonb mantém os valores como o servidor os normalizou.
timestamp with time zone
timestamptz, os mesmos instantes
Cada valor mantém o fuso que o dump escreveu, então o instante é o mesmo em qualquer fuso horário.
time, time with time zone
os mesmos tipos
Os mesmos tipos, incluindo 24:00:00.
infinity, -infinity and BC dates
mantidas
O PostgreSQL as guarda como estão.
NaN and Infinity in numeric, real and double precision
mantidos
O PostgreSQL os guarda como estão.
generated columns
as mesmas colunas geradas
A mesma fórmula, calculada pelo destino.
generated columns with functions IntoSQL doesn't write
uma coluna simples com os valores
Uma fórmula que o IntoSQL não consegue escrever deixa uma coluna simples com os valores do dump e uma linha no relatório.
Linha do relatório: generated_not_translated
defaults with functions IntoSQL doesn't write
sem valor padrão
Um valor padrão que o IntoSQL não consegue escrever fica de fora e é informado.
Linha do relatório: default_not_translated
CHECK constraints with functions IntoSQL doesn't write
não criado
Um CHECK que o IntoSQL não consegue escrever fica de fora e é informado.
Linha do relatório: check_skipped
CHECK ... NOT VALID
adicionado NOT VALID depois das linhas
As linhas que já existiam nunca foram verificadas, então o CHECK é adicionado depois delas, ainda não validado.
gin, gist, brin and hash indexes, partial and expression indexes
não criado
O IntoSQL escreve índices b-tree sobre colunas; crie os outros de novo depois da carga.
Linha do relatório: index_skipped
foreign keys to tables the dump doesn't create
não criada
Uma chave não pode apontar para uma tabela que não existe.
Linha do relatório: foreign_key_skipped
NOT NULL columns with values that become NULL
NOT NULL removido
Uma coluna cujos valores tiveram de virar NULL não pode manter NOT NULL, senão a carga pararia.
Linha do relatório: not_null_relaxed
partitioned tables
uma tabela com as linhas de todas as partições
As linhas são as mesmas; particione a tabela de novo se precisar.
Linha do relatório: partitions_dropped
views, functions, procedures, triggers, rules, policies, extensions and types other than enums
listados no relatório
O IntoSQL converte tabelas e suas linhas; o resto é listado para você recriar.
Linha do relatório: not_converted_objects
dumps without CREATE TABLE (--data-only)
tipos lidos dos valores
Um dump só de dados tem apenas linhas, então os tipos vêm dos valores.
Linha do relatório: no_schema
expressions in INSERT values
NULL
Um conversor que não executa um banco de dados não consegue avaliá-las.
Linha do relatório: expression_value
types IntoSQL doesn't know
text
O texto aceita qualquer valor; mude o tipo depois da carga.
Linha do relatório: unknown_type
text that isn't valid in its encoding
os bytes inválidos como o caractere de substituição
O texto do PostgreSQL precisa ser UTF-8 válido.
Linha do relatório: invalid_utf8_replaced
text decoded twice (ñ)
copiado como está
O dump contém exatamente esses caracteres, então eles são copiados; o relatório os aponta.
Linha do relatório: mojibake_suspected
| No arquivo | No script | Linha do relatório |
|---|---|---|
| varchar(n), char(n), text | os mesmos tiposOs mesmos tipos, com os mesmos tamanhos. | |
| numeric(p,s), numeric without a precision, NaN and Infinity | os mesmos tipos e valoresO mesmo tipo: cada dígito é copiado como o dump o escreveu. | |
| money | numeric(19,2)Como money é escrito depende do lc_monetary do servidor, então o valor fica como número sem o símbolo de moeda e carrega com qualquer localidade do destino. | type_replaced |
| enum types | os mesmos tipos enum, criados antes das tabelasOs rótulos mantêm sua ordem. | |
| enum columns holding values outside their labels | text sem CHECKO tipo rejeitaria esses valores, então a coluna é text e mantém todos eles. | enum_check_skipped |
| composite and range types the dump defines, extension types (citext, hstore, ltree, PostGIS) and multiranges | text com o texto do PostgreSQLO script não cria extensões nem tipos compostos, então cada valor mantém o texto que o PostgreSQL escreveu; crie o tipo e altere a coluna depois da carga. | type_replaced |
| citext | text, comparado de forma exataO script não cria a extensão citext, então essas colunas comparam texto de forma exata; crie-a e volte as colunas depois da carga. | case_insensitive_collation |
| json, jsonb | os mesmos tiposjson mantém o texto como foi escrito; jsonb mantém os valores como o servidor os normalizou. | |
| timestamp with time zone | timestamptz, os mesmos instantesCada valor mantém o fuso que o dump escreveu, então o instante é o mesmo em qualquer fuso horário. | |
| time, time with time zone | os mesmos tiposOs mesmos tipos, incluindo 24:00:00. | |
| infinity, -infinity and BC dates | mantidasO PostgreSQL as guarda como estão. | |
| NaN and Infinity in numeric, real and double precision | mantidosO PostgreSQL os guarda como estão. | |
| generated columns | as mesmas colunas geradasA mesma fórmula, calculada pelo destino. | |
| generated columns with functions IntoSQL doesn't write | uma coluna simples com os valoresUma fórmula que o IntoSQL não consegue escrever deixa uma coluna simples com os valores do dump e uma linha no relatório. | generated_not_translated |
| defaults with functions IntoSQL doesn't write | sem valor padrãoUm valor padrão que o IntoSQL não consegue escrever fica de fora e é informado. | default_not_translated |
| CHECK constraints with functions IntoSQL doesn't write | não criadoUm CHECK que o IntoSQL não consegue escrever fica de fora e é informado. | check_skipped |
| CHECK ... NOT VALID | adicionado NOT VALID depois das linhasAs linhas que já existiam nunca foram verificadas, então o CHECK é adicionado depois delas, ainda não validado. | |
| gin, gist, brin and hash indexes, partial and expression indexes | não criadoO IntoSQL escreve índices b-tree sobre colunas; crie os outros de novo depois da carga. | index_skipped |
| foreign keys to tables the dump doesn't create | não criadaUma chave não pode apontar para uma tabela que não existe. | foreign_key_skipped |
| NOT NULL columns with values that become NULL | NOT NULL removidoUma coluna cujos valores tiveram de virar NULL não pode manter NOT NULL, senão a carga pararia. | not_null_relaxed |
| partitioned tables | uma tabela com as linhas de todas as partiçõesAs linhas são as mesmas; particione a tabela de novo se precisar. | partitions_dropped |
| views, functions, procedures, triggers, rules, policies, extensions and types other than enums | listados no relatórioO IntoSQL converte tabelas e suas linhas; o resto é listado para você recriar. | not_converted_objects |
| dumps without CREATE TABLE (--data-only) | tipos lidos dos valoresUm dump só de dados tem apenas linhas, então os tipos vêm dos valores. | no_schema |
| expressions in INSERT values | NULLUm conversor que não executa um banco de dados não consegue avaliá-las. | expression_value |
| types IntoSQL doesn't know | textO texto aceita qualquer valor; mude o tipo depois da carga. | unknown_type |
| text that isn't valid in its encoding | os bytes inválidos como o caractere de substituiçãoO texto do PostgreSQL precisa ser UTF-8 válido. | invalid_utf8_replaced |
| text decoded twice (ñ) | copiado como estáO dump contém exatamente esses caracteres, então eles são copiados; o relatório os aponta. | mojibake_suspected |
Carregue o script no PostgreSQL
O script cria as tabelas, copia as linhas e depois adiciona chaves, índices e chaves estrangeiras, então carrega rápido e para no primeiro erro.
psql -v ON_ERROR_STOP=1 -d mydb -f postgresql.postgresql.sqlAs chaves estrangeiras são adicionadas como NOT VALID e depois validadas. Se uma linha aponta para uma linha que não existe, o script informa qual restrição, em vez de falhar no meio do caminho.
Para um dump grande, crie o banco de dados antes e execute o script com o psql na mesma máquina do servidor.
O IntoSQL Pro carrega o arquivo direto no PostgreSQL pelo app para desktop ou pela linha de comando, sem escrever um script.
Gere o dump do PostgreSQL para o melhor resultado
O conversor lê o que o dump contém. Estas opções mantêm mais dos seus dados nele:
- --format=plain, o padrão do pg_dump, escreve SQL. Um arquivo custom ou de diretório (-Fc, -Fd) vira SQL com pg_restore -f dump.sql, sem servidor de banco de dados.
- --no-owner --no-privileges deixam de fora papéis e permissões, que o conversor ignora de qualquer forma, então o dump fica menor.
- O pg_dumpall gera o dump de todos os bancos de dados em um arquivo; as tabelas de cada um recebem o nome dele, então nada colide.
O que não é convertido
Views, triggers, procedures, funções e outros objetos escritos na própria linguagem do PostgreSQL aparecem no relatório pelo nome, nunca são descartados em silêncio, para você conferir cada um com a versão do PostgreSQL em que vai carregar antes de recriá-lo.
Perguntas sobre levar o PostgreSQL entre versões
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.
Ele lê arquivos do pg_dump -Fc?
Não diretamente: um arquivo custom é um formato binário. pg_restore -f dump.sql dump.backup o transforma no SQL simples que o conversor lê, sem se conectar a um servidor. O conversor avisa quando recebe um arquivo desses.
De quais versões do PostgreSQL o dump pode vir?
Dumps escritos pelo pg_dump e pg_dumpall do PostgreSQL 10 em diante, com linhas em COPY ou INSERT. Cada dump de teste vem do PostgreSQL 13 e 18 e é comparado com a origem célula por célula.
Os valores serial e identity são mantidos?
Sim. Colunas serial e identity continuam colunas identity, cada linha mantém seu id, e cada contador continua a partir do valor que a sequência do dump tinha alcançado.
O que acontece com arrays, enums e outros tipos do PostgreSQL?
Eles ficam como estão: arrays, ranges, json e jsonb, strings de bits, exceto money. Os tipos enum são criados de novo com seus rótulos. Tipos que uma extensão traz (citext, hstore, PostGIS) e tipos compostos viram text, e o relatório diz quais colunas.
E as funções, gatilhos e visões?
Eles aparecem no relatório pelo nome e não são convertidos, para que você possa recriá-los quando as tabelas estiverem prontas. CHECKs NOT VALID são adicionados depois das linhas, ainda não validados.
Em quais versões do PostgreSQL o script carrega?
PostgreSQL 13 a 18, qualquer que seja a versão que escreveu o dump. O mesmo script carrega em cada uma delas e para no primeiro erro se algo der errado.