Einen PostgreSQL-Dump auf ein älteres oder neueres PostgreSQL bringen
Zieh einen Klartext-Dump aus pg_dump oder pg_dumpall als .sql oder .sql.gz hierher und lade ein Skript herunter, das auf PostgreSQL 13 bis 18 lädt, egal welche Version den Dump geschrieben hat. Identities, Enums, Arrays und jsonb bleiben, wie sie sind, Typen aus einer Extension werden zu Text, und jede Änderung steht im Bericht.
18 Zeilen konvertiert, keine Korrekturen, keine abgelehnt
Tabellen in shop_2024_postgres.sqlPostgreSQL-18.6-Dump · erstellt mit pg_dump · utf8mb4
customers8 Zeilen
8 Spalten 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 Zeilen
10 Spalten 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
Nicht konvertiert
- Sicht paid_orders
Jede Datenbank schreibt diese in ihrer eigenen Sprache. Schreib sie für PostgreSQL neu.
-- 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);
Korrekturen
Nichts musste korrigiert werden.
Zu prüfen
- 1 Sicht, Trigger, Routine oder Ereignis wird nicht konvertiert; der Bericht listet sie einzeln auf. Lege sie in PostgreSQL von Hand neu an.
- Der Index idx_orders_details auf orders nutzt einen Ausdruck, der sich nicht für PostgreSQL schreiben lässt (a gin index), daher wird er nicht angelegt. Lege den Index von Hand an, wenn Abfragen ihn brauchen.
Deine Datei wird auf diesem Computer umgewandelt und nie hochgeladen.
Weitere Beispiele:
Was sich zwischen Datei und Skript ändert
Jede Zeile ist eine Regel, die der Konverter anwendet, mit der Berichtszeile, die er schreibt, wenn die Regel etwas an deinen Daten ändert.
varchar(n), char(n), text
dieselben Typen
Dieselben Typen, mit denselben Längen.
numeric(p,s), numeric without a precision, NaN and Infinity
dieselben Typen und Werte
Derselbe Typ: Jede Stelle wird so kopiert, wie der Dump sie geschrieben hat.
money
numeric(19,2)
Wie money geschrieben wird, hängt vom lc_monetary des Servers ab, daher bleibt der Betrag eine Zahl ohne Währungssymbol und lädt unabhängig von der Locale des Ziels.
Berichtszeile: type_replaced
enum types
dieselben enum-Typen, vor den Tabellen angelegt
Die Labels behalten ihre Reihenfolge.
enum columns holding values outside their labels
text ohne CHECK
Der Typ würde diese Werte ablehnen, daher ist die Spalte text und behält sie alle.
Berichtszeile: enum_check_skipped
composite and range types the dump defines, extension types (citext, hstore, ltree, PostGIS) and multiranges
text mit dem Text von PostgreSQL
Das Skript legt weder Erweiterungen noch zusammengesetzte Typen an, daher behält jeder Wert den Text, den PostgreSQL geschrieben hat; lege den Typ an und ändere die Spalte nach dem Laden.
Berichtszeile: type_replaced
citext
text, exakt verglichen
Das Skript legt die Erweiterung citext nicht an, daher vergleichen diese Spalten Text exakt; lege sie an und stelle die Spalten nach dem Laden zurück.
Berichtszeile: case_insensitive_collation
json, jsonb
dieselben Typen
json behält den Text wie geschrieben; jsonb behält die Werte, wie der Server sie normalisiert hat.
timestamp with time zone
timestamptz, dieselben Zeitpunkte
Jeder Wert behält den Versatz, den der Dump geschrieben hat, daher ist der Zeitpunkt in jeder Zeitzone derselbe.
time, time with time zone
dieselben Typen
Dieselben Typen, einschließlich 24:00:00.
infinity, -infinity and BC dates
beibehalten
PostgreSQL speichert sie unverändert.
NaN and Infinity in numeric, real and double precision
beibehalten
PostgreSQL speichert sie unverändert.
generated columns
dieselben generierten Spalten
Dieselbe Formel, vom Ziel berechnet.
generated columns with functions IntoSQL doesn't write
eine normale Spalte mit den Werten
Eine Formel, die IntoSQL nicht schreiben kann, hinterlässt eine normale Spalte mit den Werten des Dumps und eine Zeile im Bericht.
Berichtszeile: generated_not_translated
defaults with functions IntoSQL doesn't write
kein Standardwert
Ein Standardwert, den IntoSQL nicht schreiben kann, wird weggelassen und gemeldet.
Berichtszeile: default_not_translated
CHECK constraints with functions IntoSQL doesn't write
nicht angelegt
Eine CHECK-Bedingung, die IntoSQL nicht schreiben kann, wird weggelassen und gemeldet.
Berichtszeile: check_skipped
CHECK ... NOT VALID
nach den Zeilen als NOT VALID hinzugefügt
Die vorher vorhandenen Zeilen wurden nie geprüft, daher wird die CHECK-Bedingung nach ihnen hinzugefügt, weiterhin nicht validiert.
gin, gist, brin and hash indexes, partial and expression indexes
nicht angelegt
IntoSQL schreibt B-Tree-Indizes auf Spalten; lege die anderen nach dem Laden neu an.
Berichtszeile: index_skipped
foreign keys to tables the dump doesn't create
nicht angelegt
Ein Schlüssel kann nicht auf eine Tabelle verweisen, die es nicht gibt.
Berichtszeile: foreign_key_skipped
NOT NULL columns with values that become NULL
NOT NULL entfernt
Eine Spalte, deren Werte NULL werden mussten, kann NOT NULL nicht behalten, sonst würde das Laden abbrechen.
Berichtszeile: not_null_relaxed
partitioned tables
eine Tabelle mit den Zeilen aller Partitionen
Die Zeilen sind dieselben; partitioniere die Tabelle neu, wenn nötig.
Berichtszeile: partitions_dropped
views, functions, procedures, triggers, rules, policies, extensions and types other than enums
im Bericht aufgeführt
IntoSQL konvertiert Tabellen und ihre Zeilen; der Rest wird aufgeführt, damit du ihn neu anlegst.
Berichtszeile: not_converted_objects
dumps without CREATE TABLE (--data-only)
Typen aus den Werten gelesen
Ein Dump nur mit Daten enthält nur Zeilen, daher kommen die Typen aus den Werten.
Berichtszeile: no_schema
expressions in INSERT values
NULL
Ein Konverter, der keine Datenbank ausführt, kann sie nicht auswerten.
Berichtszeile: expression_value
types IntoSQL doesn't know
text
Text nimmt jeden Wert auf; ändere den Typ nach dem Laden.
Berichtszeile: unknown_type
text that isn't valid in its encoding
die fehlerhaften Bytes als Ersatzzeichen
Text in PostgreSQL muss gültiges UTF-8 sein.
Berichtszeile: invalid_utf8_replaced
text decoded twice (ñ)
unverändert kopiert
Der Dump enthält genau diese Zeichen, daher werden sie kopiert; der Bericht weist auf sie hin.
Berichtszeile: mojibake_suspected
| In der Datei | Im Skript | Berichtszeile |
|---|---|---|
| varchar(n), char(n), text | dieselben TypenDieselben Typen, mit denselben Längen. | |
| numeric(p,s), numeric without a precision, NaN and Infinity | dieselben Typen und WerteDerselbe Typ: Jede Stelle wird so kopiert, wie der Dump sie geschrieben hat. | |
| money | numeric(19,2)Wie money geschrieben wird, hängt vom lc_monetary des Servers ab, daher bleibt der Betrag eine Zahl ohne Währungssymbol und lädt unabhängig von der Locale des Ziels. | type_replaced |
| enum types | dieselben enum-Typen, vor den Tabellen angelegtDie Labels behalten ihre Reihenfolge. | |
| enum columns holding values outside their labels | text ohne CHECKDer Typ würde diese Werte ablehnen, daher ist die Spalte text und behält sie alle. | enum_check_skipped |
| composite and range types the dump defines, extension types (citext, hstore, ltree, PostGIS) and multiranges | text mit dem Text von PostgreSQLDas Skript legt weder Erweiterungen noch zusammengesetzte Typen an, daher behält jeder Wert den Text, den PostgreSQL geschrieben hat; lege den Typ an und ändere die Spalte nach dem Laden. | type_replaced |
| citext | text, exakt verglichenDas Skript legt die Erweiterung citext nicht an, daher vergleichen diese Spalten Text exakt; lege sie an und stelle die Spalten nach dem Laden zurück. | case_insensitive_collation |
| json, jsonb | dieselben Typenjson behält den Text wie geschrieben; jsonb behält die Werte, wie der Server sie normalisiert hat. | |
| timestamp with time zone | timestamptz, dieselben ZeitpunkteJeder Wert behält den Versatz, den der Dump geschrieben hat, daher ist der Zeitpunkt in jeder Zeitzone derselbe. | |
| time, time with time zone | dieselben TypenDieselben Typen, einschließlich 24:00:00. | |
| infinity, -infinity and BC dates | beibehaltenPostgreSQL speichert sie unverändert. | |
| NaN and Infinity in numeric, real and double precision | beibehaltenPostgreSQL speichert sie unverändert. | |
| generated columns | dieselben generierten SpaltenDieselbe Formel, vom Ziel berechnet. | |
| generated columns with functions IntoSQL doesn't write | eine normale Spalte mit den WertenEine Formel, die IntoSQL nicht schreiben kann, hinterlässt eine normale Spalte mit den Werten des Dumps und eine Zeile im Bericht. | generated_not_translated |
| defaults with functions IntoSQL doesn't write | kein StandardwertEin Standardwert, den IntoSQL nicht schreiben kann, wird weggelassen und gemeldet. | default_not_translated |
| CHECK constraints with functions IntoSQL doesn't write | nicht angelegtEine CHECK-Bedingung, die IntoSQL nicht schreiben kann, wird weggelassen und gemeldet. | check_skipped |
| CHECK ... NOT VALID | nach den Zeilen als NOT VALID hinzugefügtDie vorher vorhandenen Zeilen wurden nie geprüft, daher wird die CHECK-Bedingung nach ihnen hinzugefügt, weiterhin nicht validiert. | |
| gin, gist, brin and hash indexes, partial and expression indexes | nicht angelegtIntoSQL schreibt B-Tree-Indizes auf Spalten; lege die anderen nach dem Laden neu an. | index_skipped |
| foreign keys to tables the dump doesn't create | nicht angelegtEin Schlüssel kann nicht auf eine Tabelle verweisen, die es nicht gibt. | foreign_key_skipped |
| NOT NULL columns with values that become NULL | NOT NULL entferntEine Spalte, deren Werte NULL werden mussten, kann NOT NULL nicht behalten, sonst würde das Laden abbrechen. | not_null_relaxed |
| partitioned tables | eine Tabelle mit den Zeilen aller PartitionenDie Zeilen sind dieselben; partitioniere die Tabelle neu, wenn nötig. | partitions_dropped |
| views, functions, procedures, triggers, rules, policies, extensions and types other than enums | im Bericht aufgeführtIntoSQL konvertiert Tabellen und ihre Zeilen; der Rest wird aufgeführt, damit du ihn neu anlegst. | not_converted_objects |
| dumps without CREATE TABLE (--data-only) | Typen aus den Werten gelesenEin Dump nur mit Daten enthält nur Zeilen, daher kommen die Typen aus den Werten. | no_schema |
| expressions in INSERT values | NULLEin Konverter, der keine Datenbank ausführt, kann sie nicht auswerten. | expression_value |
| types IntoSQL doesn't know | textText nimmt jeden Wert auf; ändere den Typ nach dem Laden. | unknown_type |
| text that isn't valid in its encoding | die fehlerhaften Bytes als ErsatzzeichenText in PostgreSQL muss gültiges UTF-8 sein. | invalid_utf8_replaced |
| text decoded twice (ñ) | unverändert kopiertDer Dump enthält genau diese Zeichen, daher werden sie kopiert; der Bericht weist auf sie hin. | mojibake_suspected |
Das Skript in PostgreSQL laden
Das Skript legt die Tabellen an, kopiert die Zeilen und fügt dann Schlüssel, Indizes und Fremdschlüssel hinzu, so lädt es schnell und hält beim ersten Fehler an.
psql -v ON_ERROR_STOP=1 -d mydb -f postgresql.postgresql.sqlFremdschlüssel werden als NOT VALID hinzugefügt und dann validiert. Verweist eine Zeile auf eine Zeile, die es nicht gibt, nennt dir das Skript den betroffenen Fremdschlüssel, statt auf halbem Weg abzubrechen.
Lege bei einem großen Dump zuerst die Datenbank an und führe das Skript mit psql auf dem Rechner aus, auf dem der Server läuft.
IntoSQL Pro lädt die Datei aus der Desktop-App oder der Kommandozeile direkt in PostgreSQL, ohne ein Skript zu schreiben.
Den PostgreSQL-Dump für das beste Ergebnis erstellen
Der Konverter liest, was der Dump enthält. Mit diesen Optionen bleibt mehr von deinen Daten darin:
- --format=plain, die Standardeinstellung von pg_dump, schreibt SQL. Ein custom- oder directory-Archiv (-Fc, -Fd) wird mit pg_restore -f dump.sql zu SQL, ohne Datenbankserver.
- --no-owner --no-privileges lassen Rollen und Rechte weg, die der Konverter ohnehin überspringt, daher wird der Dump kleiner.
- pg_dumpall schreibt jede Datenbank in eine Datei; die Tabellen jeder Datenbank werden nach ihr benannt, damit nichts kollidiert.
Was nicht konvertiert wird
Views, Trigger, Prozeduren, Funktionen und andere Objekte in der eigenen Sprache von PostgreSQL stehen mit Namen im Bericht und werden nie stillschweigend entfernt, damit du jedes vor dem Neuanlegen mit der PostgreSQL-Version abgleichen kannst, in die du lädst.
Fragen zum Wechsel von PostgreSQL zwischen Versionen
Keine Antwort gefunden? Schreib uns über die Kontaktseite, und ein Mensch antwortet. Kontaktseite
Wird mein Dump hochgeladen?
Nein. Der Konverter läuft in deinem Browser und liest den Dump stückweise von deiner Festplatte, daher verlässt er nie deinen Computer. Die Desktop-App und die Kommandozeile konvertieren ebenfalls auf deinem Computer.
Wie groß darf der Dump sein?
Der Konverter hält nie den ganzen Dump im Speicher: Er liest die Datei zweimal, in Abschnitten, und schreibt das Skript fortlaufend. Dumps von mehreren Gigabyte werden im Browser, in der Desktop-App und mit der Kommandozeile konvertiert.
Liest es pg_dump -Fc-Archive?
Nicht direkt: Ein custom-Archiv ist ein Binärformat. pg_restore -f dump.sql dump.backup wandelt es in das einfache SQL um, das der Konverter liest, ohne Verbindung zu einem Server. Der Konverter sagt das, wenn er ein Archiv bekommt.
Aus welchen PostgreSQL-Versionen kann der Dump stammen?
Dumps aus pg_dump und pg_dumpall ab PostgreSQL 10, mit COPY- oder INSERT-Zeilen. Jeder Test-Dump stammt aus PostgreSQL 13 und 18 und wird Zelle für Zelle mit seiner Quelle verglichen.
Bleiben serial- und Identity-Werte erhalten?
Ja. serial- und Identity-Spalten bleiben Identity-Spalten, jede Zeile behält ihre ID, und jeder Zähler macht bei dem Wert weiter, den die Sequenz des Dumps erreicht hatte.
Was passiert mit Arrays, enums und anderen PostgreSQL-Typen?
Sie bleiben, wie sie sind: Arrays, Ranges, json und jsonb, Bitstrings, außer money. enum-Typen werden mit ihren Labels neu angelegt. Typen aus Erweiterungen (citext, hstore, PostGIS) und zusammengesetzte Typen werden text, und der Bericht nennt die Spalten.
Was ist mit Funktionen, Triggern und Sichten?
Sie stehen mit Namen im Bericht und werden nicht konvertiert, damit du sie neu anlegen kannst, sobald die Tabellen da sind. NOT VALID-CHECK-Bedingungen werden nach den Zeilen hinzugefügt, weiterhin nicht validiert.
Auf welchen PostgreSQL-Versionen lädt das Skript?
PostgreSQL 13 bis 18, egal welche Version den Dump geschrieben hat. Dasselbe Skript lädt auf jeder davon und hält beim ersten Fehler an, falls etwas schiefgeht.