Zum Inhalt springen
IntoSQL-Startseite

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.

Deine Datei
sqlshop_2024_postgres.sqlBeispieldatei, 6,2 kB
Deine Datenbank

18 Zeilen konvertiert, keine Korrekturen, keine abgelehnt

Anzeigen

Tabellen in shop_2024_postgres.sqlPostgreSQL-18.6-Dump · erstellt mit pg_dump · utf8mb4

  • customers8 Zeilen
    8 Spalten
    idinteger not null
    nametext not null
    emailtext not null
    countryvarchar(2) not null
    is_activeboolean not null
    tagstext[] not null
    signed_update
    created_attimestamptz(6) not null
  • orders10 Zeilen
    10 Spalten
    idinteger not null
    customer_idinteger not null
    statusorder_status not null
    totalnumeric(10,2) not null
    itemssmallint not null
    ordered_attimestamp(6) not null
    shipped_attimestamp(6)
    notetext
    detailsjsonb
    deliveryinterval

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 DateiIm SkriptBerichtszeile
varchar(n), char(n), textdieselben TypenDieselben Typen, mit denselben Längen.
numeric(p,s), numeric without a precision, NaN and Infinitydieselben Typen und WerteDerselbe Typ: Jede Stelle wird so kopiert, wie der Dump sie geschrieben hat.
moneynumeric(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 typesdieselben enum-Typen, vor den Tabellen angelegtDie Labels behalten ihre Reihenfolge.
enum columns holding values outside their labelstext 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 multirangestext 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
citexttext, 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, jsonbdieselben Typenjson behält den Text wie geschrieben; jsonb behält die Werte, wie der Server sie normalisiert hat.
timestamp with time zonetimestamptz, dieselben ZeitpunkteJeder Wert behält den Versatz, den der Dump geschrieben hat, daher ist der Zeitpunkt in jeder Zeitzone derselbe.
time, time with time zonedieselben TypenDieselben Typen, einschließlich 24:00:00.
infinity, -infinity and BC datesbeibehaltenPostgreSQL speichert sie unverändert.
NaN and Infinity in numeric, real and double precisionbeibehaltenPostgreSQL speichert sie unverändert.
generated columnsdieselben generierten SpaltenDieselbe Formel, vom Ziel berechnet.
generated columns with functions IntoSQL doesn't writeeine 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 writekein StandardwertEin Standardwert, den IntoSQL nicht schreiben kann, wird weggelassen und gemeldet.default_not_translated
CHECK constraints with functions IntoSQL doesn't writenicht angelegtEine CHECK-Bedingung, die IntoSQL nicht schreiben kann, wird weggelassen und gemeldet.check_skipped
CHECK ... NOT VALIDnach 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 indexesnicht 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 createnicht angelegtEin Schlüssel kann nicht auf eine Tabelle verweisen, die es nicht gibt.foreign_key_skipped
NOT NULL columns with values that become NULLNOT NULL entferntEine Spalte, deren Werte NULL werden mussten, kann NOT NULL nicht behalten, sonst würde das Laden abbrechen.not_null_relaxed
partitioned tableseine 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 enumsim 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 valuesNULLEin Konverter, der keine Datenbank ausführt, kann sie nicht auswerten.expression_value
types IntoSQL doesn't knowtextText nimmt jeden Wert auf; ändere den Typ nach dem Laden.unknown_type
text that isn't valid in its encodingdie 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.sql

Fremdschlü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.