Pasa un volcado de PostgreSQL a un PostgreSQL más antiguo o más nuevo
Suelta un volcado plano de pg_dump o pg_dumpall, como .sql o .sql.gz, y descarga un script que carga en PostgreSQL 13 a 18, sin importar qué versión escribió el volcado. Las identidades, enums, arreglos y jsonb quedan igual, los tipos que trae una extensión se vuelven texto, y cada cambio aparece en el informe.
18 filas convertidas, sin correcciones, ninguna rechazada
Tablas en shop_2024_postgres.sqlVolcado de PostgreSQL 18.6 · escrito por pg_dump · utf8mb4
customers8 filas
8 columnas 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 filas
10 columnas 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
Sin convertir
- Vista paid_orders
Cada base de datos los escribe en su propio lenguaje. Reescríbelos para 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);
Correcciones
No hubo nada que corregir.
Para revisar
- 1 vista, disparador, rutina o evento no se convierte; el informe lista cada uno. Vuelve a crearlos a mano en PostgreSQL.
- El índice idx_orders_details de orders usa una expresión que no se puede escribir para PostgreSQL (a gin index), así que no se crea. Crea el índice a mano si las consultas lo necesitan.
Tu archivo se convierte en esta computadora y nunca se sube.
Otros ejemplos:
Qué cambia entre el archivo y el script
Cada fila es una regla que aplica el convertidor, con la línea que escribe en el informe cuando la regla cambia algo en tus datos.
varchar(n), char(n), text
los mismos tipos
Los mismos tipos, con las mismas longitudes.
numeric(p,s), numeric without a precision, NaN and Infinity
los mismos tipos y valores
El mismo tipo: cada dígito se copia como lo escribió el volcado.
money
numeric(19,2)
Cómo se escribe money depende del lc_monetary del servidor, así que el importe se guarda como número sin el símbolo de moneda, y carga sea cual sea la configuración regional del destino.
Línea del informe: type_replaced
enum types
los mismos tipos enum, creados antes de las tablas
Las etiquetas conservan su orden.
enum columns holding values outside their labels
text sin CHECK
El tipo rechazaría esos valores, así que la columna es text y los conserva todos.
Línea del informe: enum_check_skipped
composite and range types the dump defines, extension types (citext, hstore, ltree, PostGIS) and multiranges
text con el texto de PostgreSQL
El script no crea extensiones ni tipos compuestos, así que cada valor conserva el texto que escribió PostgreSQL; crea el tipo y modifica la columna después de cargar.
Línea del informe: type_replaced
citext
text, con comparación exacta
El script no crea la extensión citext, así que estas columnas comparan el texto exactamente; créala y vuelve a cambiar las columnas después de cargar.
Línea del informe: case_insensitive_collation
json, jsonb
los mismos tipos
json conserva el texto como se escribió; jsonb conserva los valores como los normalizó el servidor.
timestamp with time zone
timestamptz, los mismos instantes
Cada valor conserva el desfase que escribió el volcado, así que el instante es el mismo en cualquier zona horaria.
time, time with time zone
los mismos tipos
Los mismos tipos, 24:00:00 incluido.
infinity, -infinity and BC dates
se conservan
PostgreSQL los guarda tal cual.
NaN and Infinity in numeric, real and double precision
se conservan
PostgreSQL los guarda tal cual.
generated columns
las mismas columnas generadas
La misma fórmula, calculada por el destino.
generated columns with functions IntoSQL doesn't write
una columna simple con los valores
Una fórmula que IntoSQL no puede escribir deja una columna simple con los valores del volcado y una línea en el informe.
Línea del informe: generated_not_translated
defaults with functions IntoSQL doesn't write
sin valor predeterminado
Un valor predeterminado que IntoSQL no puede escribir se deja fuera y aparece en el informe.
Línea del informe: default_not_translated
CHECK constraints with functions IntoSQL doesn't write
no se crea
Un CHECK que IntoSQL no puede escribir se deja fuera y aparece en el informe.
Línea del informe: check_skipped
CHECK ... NOT VALID
agregado NOT VALID después de las filas
Las filas que ya estaban nunca se comprobaron, así que el CHECK se agrega después de ellas, todavía sin validar.
gin, gist, brin and hash indexes, partial and expression indexes
no se crea
IntoSQL escribe índices b-tree sobre columnas; vuelve a crear los demás después de cargar.
Línea del informe: index_skipped
foreign keys to tables the dump doesn't create
no se crea
Una clave no puede nombrar una tabla que no existe.
Línea del informe: foreign_key_skipped
NOT NULL columns with values that become NULL
sin NOT NULL
Una columna cuyos valores tuvieron que volverse NULL no puede conservar NOT NULL, o la carga se detendría.
Línea del informe: not_null_relaxed
partitioned tables
una tabla con las filas de todas las particiones
Las filas son las mismas; vuelve a particionar la tabla si lo necesita.
Línea del informe: partitions_dropped
views, functions, procedures, triggers, rules, policies, extensions and types other than enums
listados en el informe
IntoSQL convierte las tablas y sus filas; el resto se lista para que lo vuelvas a crear.
Línea del informe: not_converted_objects
dumps without CREATE TABLE (--data-only)
tipos leídos de los valores
Un volcado solo de datos solo tiene filas, así que los tipos salen de los valores.
Línea del informe: no_schema
expressions in INSERT values
NULL
Un convertidor que no ejecuta una base de datos no puede evaluarlas.
Línea del informe: expression_value
types IntoSQL doesn't know
text
El texto admite cualquier valor; cambia el tipo después de cargar.
Línea del informe: unknown_type
text that isn't valid in its encoding
los bytes incorrectos como carácter de reemplazo
El texto de PostgreSQL tiene que ser UTF-8 válido.
Línea del informe: invalid_utf8_replaced
text decoded twice (ñ)
se copia tal cual
El volcado contiene exactamente estos caracteres, así que se copian; el informe los señala.
Línea del informe: mojibake_suspected
| En el archivo | En el script | Línea del informe |
|---|---|---|
| varchar(n), char(n), text | los mismos tiposLos mismos tipos, con las mismas longitudes. | |
| numeric(p,s), numeric without a precision, NaN and Infinity | los mismos tipos y valoresEl mismo tipo: cada dígito se copia como lo escribió el volcado. | |
| money | numeric(19,2)Cómo se escribe money depende del lc_monetary del servidor, así que el importe se guarda como número sin el símbolo de moneda, y carga sea cual sea la configuración regional del destino. | type_replaced |
| enum types | los mismos tipos enum, creados antes de las tablasLas etiquetas conservan su orden. | |
| enum columns holding values outside their labels | text sin CHECKEl tipo rechazaría esos valores, así que la columna es text y los conserva todos. | enum_check_skipped |
| composite and range types the dump defines, extension types (citext, hstore, ltree, PostGIS) and multiranges | text con el texto de PostgreSQLEl script no crea extensiones ni tipos compuestos, así que cada valor conserva el texto que escribió PostgreSQL; crea el tipo y modifica la columna después de cargar. | type_replaced |
| citext | text, con comparación exactaEl script no crea la extensión citext, así que estas columnas comparan el texto exactamente; créala y vuelve a cambiar las columnas después de cargar. | case_insensitive_collation |
| json, jsonb | los mismos tiposjson conserva el texto como se escribió; jsonb conserva los valores como los normalizó el servidor. | |
| timestamp with time zone | timestamptz, los mismos instantesCada valor conserva el desfase que escribió el volcado, así que el instante es el mismo en cualquier zona horaria. | |
| time, time with time zone | los mismos tiposLos mismos tipos, 24:00:00 incluido. | |
| infinity, -infinity and BC dates | se conservanPostgreSQL los guarda tal cual. | |
| NaN and Infinity in numeric, real and double precision | se conservanPostgreSQL los guarda tal cual. | |
| generated columns | las mismas columnas generadasLa misma fórmula, calculada por el destino. | |
| generated columns with functions IntoSQL doesn't write | una columna simple con los valoresUna fórmula que IntoSQL no puede escribir deja una columna simple con los valores del volcado y una línea en el informe. | generated_not_translated |
| defaults with functions IntoSQL doesn't write | sin valor predeterminadoUn valor predeterminado que IntoSQL no puede escribir se deja fuera y aparece en el informe. | default_not_translated |
| CHECK constraints with functions IntoSQL doesn't write | no se creaUn CHECK que IntoSQL no puede escribir se deja fuera y aparece en el informe. | check_skipped |
| CHECK ... NOT VALID | agregado NOT VALID después de las filasLas filas que ya estaban nunca se comprobaron, así que el CHECK se agrega después de ellas, todavía sin validar. | |
| gin, gist, brin and hash indexes, partial and expression indexes | no se creaIntoSQL escribe índices b-tree sobre columnas; vuelve a crear los demás después de cargar. | index_skipped |
| foreign keys to tables the dump doesn't create | no se creaUna clave no puede nombrar una tabla que no existe. | foreign_key_skipped |
| NOT NULL columns with values that become NULL | sin NOT NULLUna columna cuyos valores tuvieron que volverse NULL no puede conservar NOT NULL, o la carga se detendría. | not_null_relaxed |
| partitioned tables | una tabla con las filas de todas las particionesLas filas son las mismas; vuelve a particionar la tabla si lo necesita. | partitions_dropped |
| views, functions, procedures, triggers, rules, policies, extensions and types other than enums | listados en el informeIntoSQL convierte las tablas y sus filas; el resto se lista para que lo vuelvas a crear. | not_converted_objects |
| dumps without CREATE TABLE (--data-only) | tipos leídos de los valoresUn volcado solo de datos solo tiene filas, así que los tipos salen de los valores. | no_schema |
| expressions in INSERT values | NULLUn convertidor que no ejecuta una base de datos no puede evaluarlas. | expression_value |
| types IntoSQL doesn't know | textEl texto admite cualquier valor; cambia el tipo después de cargar. | unknown_type |
| text that isn't valid in its encoding | los bytes incorrectos como carácter de reemplazoEl texto de PostgreSQL tiene que ser UTF-8 válido. | invalid_utf8_replaced |
| text decoded twice (ñ) | se copia tal cualEl volcado contiene exactamente estos caracteres, así que se copian; el informe los señala. | mojibake_suspected |
Carga el script en PostgreSQL
El script crea las tablas, copia las filas y luego agrega claves, índices y claves foráneas, así que carga rápido y se detiene en el primer error.
psql -v ON_ERROR_STOP=1 -d mydb -f postgresql.postgresql.sqlLas claves foráneas se agregan como NOT VALID y luego se validan. Si una fila apunta a una fila que no existe, el script te dice qué restricción es, en lugar de fallar a medias.
Para un volcado grande, crea primero la base de datos y ejecuta el script con psql desde la misma máquina que el servidor.
IntoSQL Pro carga el archivo directo en PostgreSQL desde la app de escritorio o la línea de comandos, sin escribir un script.
Haz el volcado de PostgreSQL para el mejor resultado
El convertidor lee lo que contiene el volcado. Estas opciones conservan más de tus datos en él:
- --format=plain, el formato predeterminado de pg_dump, escribe SQL. Un archivo custom o de directorio (-Fc, -Fd) pasa a SQL con pg_restore -f dump.sql, sin un servidor de base de datos.
- --no-owner --no-privileges dejan fuera los roles y los permisos, que el convertidor omite de todos modos, así que el volcado es más pequeño.
- pg_dumpall vuelca todas las bases de datos en un archivo; las tablas de cada una llevan su nombre, así que nada choca.
Qué no se convierte
Las vistas, disparadores, procedimientos, funciones y otros objetos escritos en el propio lenguaje de PostgreSQL aparecen en el informe por nombre, nunca se descartan en silencio, para que revises cada uno contra la versión de PostgreSQL en la que cargas antes de recrearlo.
Preguntas sobre pasar PostgreSQL entre versiones
¿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.
¿Lee archivos de pg_dump -Fc?
No directamente: un archivo custom tiene formato binario. pg_restore -f dump.sql dump.backup lo pasa al SQL plano que lee el convertidor, sin conectarse a un servidor. El convertidor lo indica cuando recibe un archivo así.
¿De qué versiones de PostgreSQL puede venir el volcado?
Volcados escritos por pg_dump y pg_dumpall de PostgreSQL 10 en adelante, con filas COPY o INSERT. Cada volcado de prueba viene de PostgreSQL 13 y 18 y se compara con su origen celda por celda.
¿Se conservan los valores serial e identity?
Sí. Las columnas serial e identity siguen siendo columnas de identidad, cada fila conserva su id, y cada contador sigue desde el valor que había alcanzado la secuencia del volcado.
¿Qué pasa con los arreglos, los enum y otros tipos de PostgreSQL?
Se quedan tal cual: arreglos, rangos, json y jsonb, cadenas de bits, salvo money. Los tipos enum se vuelven a crear con sus etiquetas. Los tipos de una extensión (citext, hstore, PostGIS) y los tipos compuestos se vuelven text, y el informe dice qué columnas.
¿Qué pasa con las funciones, los disparadores y las vistas?
Aparecen en el informe por nombre y no se convierten, para que puedas volver a crearlos una vez cargadas las tablas. Los CHECK NOT VALID se agregan después de las filas, todavía sin validar.
¿En qué versiones de PostgreSQL carga el script?
PostgreSQL 13 a 18, sea cual sea la versión que escribió el volcado. El mismo script carga en cada una, y se detiene en el primer error si algo sale mal.