Passer un dump PostgreSQL vers un PostgreSQL plus ancien ou plus récent
Déposez un dump texte de pg_dump ou pg_dumpall, en .sql ou .sql.gz, et téléchargez un script qui se charge sur PostgreSQL 13 à 18, quelle que soit la version qui a écrit le dump. Identités, enums, tableaux et jsonb restent tels quels, les types apportés par une extension deviennent du texte, et chaque changement figure dans le rapport.
18 lignes converties, aucune correction, aucune rejetée
Tables de shop_2024_postgres.sqlDump PostgreSQL 18.6 · écrit par pg_dump · utf8mb4
customers8 lignes
8 colonnes 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 lignes
10 colonnes 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
Non converti
- Vue paid_orders
Chaque base de données les écrit dans son propre langage. Réécrivez-les pour 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);
Corrections
Rien n'avait besoin d'être corrigé.
À vérifier
- 1 objet non converti (vues, déclencheurs, routines ou événements) ; le rapport les liste un par un. Recréez-les à la main dans PostgreSQL.
- L'index idx_orders_details sur orders utilise une expression qui ne peut pas être écrite pour PostgreSQL (a gin index) ; il n'est donc pas créé. Créez l'index à la main si les requêtes en ont besoin.
Votre fichier est converti sur cet ordinateur et n'est jamais envoyé.
Autres exemples :
Ce qui change entre le fichier et le script
Chaque ligne est une règle appliquée par le convertisseur, avec la ligne de rapport qu'il écrit quand la règle change quelque chose dans vos données.
varchar(n), char(n), text
les mêmes types
Les mêmes types, avec les mêmes longueurs.
numeric(p,s), numeric without a precision, NaN and Infinity
les mêmes types et valeurs
Le même type : chaque chiffre est copié tel que le dump l'a écrit.
money
numeric(19,2)
L'écriture de money dépend du lc_monetary du serveur ; le montant est donc gardé comme nombre sans symbole monétaire, et il se charge quelle que soit la locale de la cible.
Ligne du rapport: type_replaced
enum types
les mêmes types enum, créés avant les tables
Les libellés gardent leur ordre.
enum columns holding values outside their labels
text sans CHECK
Le type rejetterait ces valeurs ; la colonne est donc en text et les garde toutes.
Ligne du rapport: enum_check_skipped
composite and range types the dump defines, extension types (citext, hstore, ltree, PostGIS) and multiranges
text avec le texte de PostgreSQL
Le script ne crée ni extensions ni types composites ; chaque valeur garde donc le texte écrit par PostgreSQL. Créez le type et modifiez la colonne après le chargement.
Ligne du rapport: type_replaced
citext
text, comparé exactement
Le script ne crée pas l'extension citext ; ces colonnes comparent donc le texte exactement. Créez-la et rétablissez les colonnes après le chargement.
Ligne du rapport: case_insensitive_collation
json, jsonb
les mêmes types
json garde le texte tel qu'écrit ; jsonb garde les valeurs telles que le serveur les a normalisées.
timestamp with time zone
timestamptz, les mêmes instants
Chaque valeur garde le décalage écrit par le dump, donc l'instant est le même dans tout fuseau horaire.
time, time with time zone
les mêmes types
Les mêmes types, 24:00:00 compris.
infinity, -infinity and BC dates
conservées
PostgreSQL les garde telles quelles.
NaN and Infinity in numeric, real and double precision
conservées
PostgreSQL les garde telles quelles.
generated columns
les mêmes colonnes générées
La même formule, calculée par la cible.
generated columns with functions IntoSQL doesn't write
une colonne simple avec les valeurs
Une formule qu'IntoSQL ne sait pas écrire laisse une colonne simple avec les valeurs du dump et une ligne dans le rapport.
Ligne du rapport: generated_not_translated
defaults with functions IntoSQL doesn't write
aucune valeur par défaut
Une valeur par défaut qu'IntoSQL ne sait pas écrire est omise et signalée.
Ligne du rapport: default_not_translated
CHECK constraints with functions IntoSQL doesn't write
non créée
Une contrainte CHECK qu'IntoSQL ne sait pas écrire est omise et signalée.
Ligne du rapport: check_skipped
CHECK ... NOT VALID
ajoutée NOT VALID après les lignes
Les lignes déjà présentes n'ont jamais été vérifiées ; la contrainte est donc ajoutée après elles, toujours non validée.
gin, gist, brin and hash indexes, partial and expression indexes
non créé
IntoSQL écrit des index b-tree sur des colonnes ; recréez les autres après le chargement.
Ligne du rapport: index_skipped
foreign keys to tables the dump doesn't create
non créée
Une clé ne peut pas désigner une table absente.
Ligne du rapport: foreign_key_skipped
NOT NULL columns with values that become NULL
NOT NULL retiré
Une colonne dont des valeurs ont dû devenir NULL ne peut pas garder NOT NULL, sinon le chargement s'arrêterait.
Ligne du rapport: not_null_relaxed
partitioned tables
une seule table avec les lignes de chaque partition
Les lignes sont les mêmes ; partitionnez à nouveau la table si besoin.
Ligne du rapport: partitions_dropped
views, functions, procedures, triggers, rules, policies, extensions and types other than enums
listés dans le rapport
IntoSQL convertit les tables et leurs lignes ; le reste est listé pour que vous le recréiez.
Ligne du rapport: not_converted_objects
dumps without CREATE TABLE (--data-only)
types déduits des valeurs
Un dump de données seules ne contient que des lignes, donc les types viennent des valeurs.
Ligne du rapport: no_schema
expressions in INSERT values
NULL
Un convertisseur qui n'exécute pas de base de données ne peut pas les évaluer.
Ligne du rapport: expression_value
types IntoSQL doesn't know
text
Le texte accepte toute valeur ; changez le type après le chargement.
Ligne du rapport: unknown_type
text that isn't valid in its encoding
les octets invalides deviennent le caractère de remplacement
Le texte PostgreSQL doit être de l'UTF-8 valide.
Ligne du rapport: invalid_utf8_replaced
text decoded twice (ñ)
copié tel quel
Le dump contient exactement ces caractères, ils sont donc copiés ; le rapport les signale.
Ligne du rapport: mojibake_suspected
| Dans le fichier | Dans le script | Ligne du rapport |
|---|---|---|
| varchar(n), char(n), text | les mêmes typesLes mêmes types, avec les mêmes longueurs. | |
| numeric(p,s), numeric without a precision, NaN and Infinity | les mêmes types et valeursLe même type : chaque chiffre est copié tel que le dump l'a écrit. | |
| money | numeric(19,2)L'écriture de money dépend du lc_monetary du serveur ; le montant est donc gardé comme nombre sans symbole monétaire, et il se charge quelle que soit la locale de la cible. | type_replaced |
| enum types | les mêmes types enum, créés avant les tablesLes libellés gardent leur ordre. | |
| enum columns holding values outside their labels | text sans CHECKLe type rejetterait ces valeurs ; la colonne est donc en text et les garde toutes. | enum_check_skipped |
| composite and range types the dump defines, extension types (citext, hstore, ltree, PostGIS) and multiranges | text avec le texte de PostgreSQLLe script ne crée ni extensions ni types composites ; chaque valeur garde donc le texte écrit par PostgreSQL. Créez le type et modifiez la colonne après le chargement. | type_replaced |
| citext | text, comparé exactementLe script ne crée pas l'extension citext ; ces colonnes comparent donc le texte exactement. Créez-la et rétablissez les colonnes après le chargement. | case_insensitive_collation |
| json, jsonb | les mêmes typesjson garde le texte tel qu'écrit ; jsonb garde les valeurs telles que le serveur les a normalisées. | |
| timestamp with time zone | timestamptz, les mêmes instantsChaque valeur garde le décalage écrit par le dump, donc l'instant est le même dans tout fuseau horaire. | |
| time, time with time zone | les mêmes typesLes mêmes types, 24:00:00 compris. | |
| infinity, -infinity and BC dates | conservéesPostgreSQL les garde telles quelles. | |
| NaN and Infinity in numeric, real and double precision | conservéesPostgreSQL les garde telles quelles. | |
| generated columns | les mêmes colonnes généréesLa même formule, calculée par la cible. | |
| generated columns with functions IntoSQL doesn't write | une colonne simple avec les valeursUne formule qu'IntoSQL ne sait pas écrire laisse une colonne simple avec les valeurs du dump et une ligne dans le rapport. | generated_not_translated |
| defaults with functions IntoSQL doesn't write | aucune valeur par défautUne valeur par défaut qu'IntoSQL ne sait pas écrire est omise et signalée. | default_not_translated |
| CHECK constraints with functions IntoSQL doesn't write | non crééeUne contrainte CHECK qu'IntoSQL ne sait pas écrire est omise et signalée. | check_skipped |
| CHECK ... NOT VALID | ajoutée NOT VALID après les lignesLes lignes déjà présentes n'ont jamais été vérifiées ; la contrainte est donc ajoutée après elles, toujours non validée. | |
| gin, gist, brin and hash indexes, partial and expression indexes | non crééIntoSQL écrit des index b-tree sur des colonnes ; recréez les autres après le chargement. | index_skipped |
| foreign keys to tables the dump doesn't create | non crééeUne clé ne peut pas désigner une table absente. | foreign_key_skipped |
| NOT NULL columns with values that become NULL | NOT NULL retiréUne colonne dont des valeurs ont dû devenir NULL ne peut pas garder NOT NULL, sinon le chargement s'arrêterait. | not_null_relaxed |
| partitioned tables | une seule table avec les lignes de chaque partitionLes lignes sont les mêmes ; partitionnez à nouveau la table si besoin. | partitions_dropped |
| views, functions, procedures, triggers, rules, policies, extensions and types other than enums | listés dans le rapportIntoSQL convertit les tables et leurs lignes ; le reste est listé pour que vous le recréiez. | not_converted_objects |
| dumps without CREATE TABLE (--data-only) | types déduits des valeursUn dump de données seules ne contient que des lignes, donc les types viennent des valeurs. | no_schema |
| expressions in INSERT values | NULLUn convertisseur qui n'exécute pas de base de données ne peut pas les évaluer. | expression_value |
| types IntoSQL doesn't know | textLe texte accepte toute valeur ; changez le type après le chargement. | unknown_type |
| text that isn't valid in its encoding | les octets invalides deviennent le caractère de remplacementLe texte PostgreSQL doit être de l'UTF-8 valide. | invalid_utf8_replaced |
| text decoded twice (ñ) | copié tel quelLe dump contient exactement ces caractères, ils sont donc copiés ; le rapport les signale. | mojibake_suspected |
Charger le script dans PostgreSQL
Le script crée les tables, copie les lignes, puis ajoute les clés, les index et les clés étrangères ; il se charge donc vite et s'arrête à la première erreur.
psql -v ON_ERROR_STOP=1 -d mydb -f postgresql.postgresql.sqlLes clés étrangères sont ajoutées en NOT VALID, puis validées. Si une ligne pointe vers une ligne qui n'existe pas, le script vous indique quelle contrainte, au lieu d'échouer à mi-chemin.
Pour un gros dump, créez d'abord la base de données et exécutez le script avec psql depuis la machine du serveur.
IntoSQL Pro charge le fichier directement dans PostgreSQL depuis l'application de bureau ou la ligne de commande, sans écrire de script.
Faire le dump PostgreSQL pour un meilleur résultat
Le convertisseur lit ce que contient le dump. Ces options y gardent davantage de vos données :
- --format=plain, le format par défaut de pg_dump, écrit du SQL. Une archive custom ou directory (-Fc, -Fd) devient du SQL avec pg_restore -f dump.sql, sans serveur de base de données.
- --no-owner --no-privileges omettent les rôles et les droits, que le convertisseur ignore de toute façon ; le dump est donc plus petit.
- pg_dumpall met toutes les bases de données dans un seul fichier ; les tables de chacune sont préfixées par son nom, donc rien n'entre en collision.
Ce qui n'est pas converti
Les vues, triggers, procédures, fonctions et autres objets écrits dans le propre langage de PostgreSQL sont listés par nom dans le rapport, jamais supprimés en silence, pour que vous vérifiiez chacun face à la version de PostgreSQL cible avant de le recréer.
Questions sur le passage de PostgreSQL d'une version à l'autre
Pas de réponse ici ? Écrivez-nous depuis la page de contact, une personne vous répond. Page de contact
Mon dump est-il envoyé ?
Non. Le convertisseur s'exécute dans votre navigateur et lit le dump depuis votre disque par morceaux ; il ne quitte donc jamais votre ordinateur. L'application de bureau et la ligne de commande convertissent aussi sur votre ordinateur.
Quelle taille peut avoir le dump ?
Le convertisseur ne garde jamais tout le dump en mémoire : il lit le fichier deux fois, par plages, et écrit le script au fur et à mesure. Les dumps de plusieurs gigaoctets se convertissent dans le navigateur, dans l'application de bureau et avec la ligne de commande.
Lit-il les archives pg_dump -Fc ?
Pas directement : une archive custom est un format binaire. pg_restore -f dump.sql dump.backup la transforme en SQL texte que le convertisseur lit, sans se connecter à un serveur. Le convertisseur le signale quand il reçoit une archive.
De quelles versions de PostgreSQL le dump peut-il venir ?
Les dumps écrits par pg_dump et pg_dumpall depuis PostgreSQL 10, avec des lignes COPY ou INSERT. Chaque dump de test vient de PostgreSQL 13 et 18 et est comparé à sa source cellule par cellule.
Les valeurs serial et identity sont-elles conservées ?
Oui. Les colonnes serial et identity restent des colonnes d'identité, chaque ligne garde son identifiant, et chaque compteur reprend à la valeur qu'avait atteinte la séquence du dump.
Que deviennent les tableaux, les enums et les autres types PostgreSQL ?
Ils restent tels quels : tableaux, plages, json et jsonb, chaînes de bits, sauf money. Les types enum sont recréés avec leurs libellés. Les types apportés par une extension (citext, hstore, PostGIS) et les types composites deviennent text, et le rapport indique quelles colonnes.
Et les fonctions, les déclencheurs et les vues ?
Ils sont listés par nom dans le rapport et ne sont pas convertis, pour que vous puissiez les recréer une fois les tables chargées. Les contraintes CHECK NOT VALID sont ajoutées après les lignes, toujours non validées.
Sur quelles versions de PostgreSQL le script se charge-t-il ?
PostgreSQL 13 à 18, quelle que soit la version qui a écrit le dump. Le même script se charge sur chacune, et s'arrête à la première erreur en cas de problème.