Перенесите дамп PostgreSQL на более старую или новую версию PostgreSQL
Перетащите обычный дамп из pg_dump или pg_dumpall в формате .sql или .sql.gz и скачайте один скрипт, который загружается на PostgreSQL с 13 по 18, какая бы версия ни записала дамп. Identity, enum, массивы и jsonb остаются как есть, типы из расширений становятся text, и каждое изменение указано в отчете.
18 строк конвертировано, без исправлений, ни одна не отклонена
Таблицы в shop_2024_postgres.sqlДамп PostgreSQL 18.6 · создан программой pg_dump · utf8mb4
customers8 строк
8 столбцов 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 строк
10 столбцов 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
Не конвертировано
- Представление paid_orders
Каждая база данных пишет их на своем языке. Перепишите их для 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);
Исправления
Исправлять ничего не пришлось.
Требует проверки
- Не конвертированы представления, триггеры, процедуры и события (1 объект); отчет перечисляет каждый. Создайте их заново вручную в PostgreSQL.
- Индекс idx_orders_details таблицы orders использует выражение, которое нельзя записать для PostgreSQL (a gin index), поэтому он не создан. Создайте индекс вручную, если он нужен запросам.
Файл конвертируется на этом компьютере и никуда не загружается.
Другие примеры:
Что меняется между файлом и скриптом
Каждая строка - это правило, которое применяет конвертер, и строка отчета, которую он пишет, когда правило что-то меняет в ваших данных.
varchar(n), char(n), text
те же типы
Те же типы с теми же длинами.
numeric(p,s), numeric without a precision, NaN and Infinity
те же типы и значения
Тот же тип: каждая цифра копируется так, как ее записал дамп.
money
numeric(19,2)
Запись money зависит от lc_monetary сервера, поэтому сумма хранится как число без символа валюты и загружается при любой локали целевой базы.
Строка отчета: type_replaced
enum types
те же типы enum, создаются до таблиц
Метки сохраняют свой порядок.
enum columns holding values outside their labels
text без проверки
Тип отклонил бы эти значения, поэтому столбец имеет тип text и сохраняет их все.
Строка отчета: enum_check_skipped
composite and range types the dump defines, extension types (citext, hstore, ltree, PostGIS) and multiranges
text с текстом PostgreSQL
Скрипт не создает ни расширения, ни составные типы, поэтому каждое значение сохраняет текст, записанный PostgreSQL; после загрузки создайте тип и измените столбец.
Строка отчета: type_replaced
citext
text, точное сравнение
Скрипт не создает расширение citext, поэтому эти столбцы сравнивают текст точно; после загрузки создайте его и верните столбцам прежний тип.
Строка отчета: case_insensitive_collation
json, jsonb
те же типы
json хранит текст в исходном виде; jsonb хранит значения так, как их нормализовал сервер.
timestamp with time zone
timestamptz, те же моменты
Каждое значение сохраняет смещение, записанное дампом, поэтому момент один и тот же в любом часовом поясе.
time, time with time zone
те же типы
Те же типы, включая 24:00:00.
infinity, -infinity and BC dates
сохраняется
PostgreSQL хранит их как есть.
NaN and Infinity in numeric, real and double precision
сохраняется
PostgreSQL хранит их как есть.
generated columns
те же генерируемые столбцы
Та же формула, которую вычисляет целевая база.
generated columns with functions IntoSQL doesn't write
обычный столбец со значениями
Формула, которую IntoSQL не может записать, оставляет обычный столбец со значениями из дампа и строку в отчете.
Строка отчета: generated_not_translated
defaults with functions IntoSQL doesn't write
без значения по умолчанию
Значение по умолчанию, которое IntoSQL не может записать, опускается и попадает в отчет.
Строка отчета: default_not_translated
CHECK constraints with functions IntoSQL doesn't write
не создается
Проверка, которую IntoSQL не может записать, опускается и попадает в отчет.
Строка отчета: check_skipped
CHECK ... NOT VALID
добавляется как NOT VALID после строк
Строки, которые были до нее, не проверялись, поэтому проверка добавляется после них и остается NOT VALID.
gin, gist, brin and hash indexes, partial and expression indexes
не создается
IntoSQL пишет индексы b-tree по столбцам; остальные создайте заново после загрузки.
Строка отчета: index_skipped
foreign keys to tables the dump doesn't create
не создается
Ключ не может ссылаться на таблицу, которой нет.
Строка отчета: foreign_key_skipped
NOT NULL columns with values that become NULL
NOT NULL снимается
Столбец, значения которого пришлось заменить на NULL, не может сохранить NOT NULL, иначе загрузка остановится.
Строка отчета: not_null_relaxed
partitioned tables
одна таблица со строками всех секций
Строки те же; при необходимости секционируйте таблицу заново.
Строка отчета: partitions_dropped
views, functions, procedures, triggers, rules, policies, extensions and types other than enums
перечисляются в отчете
IntoSQL конвертирует таблицы и их строки; остальное перечислено, чтобы вы создали его заново.
Строка отчета: not_converted_objects
dumps without CREATE TABLE (--data-only)
типы определяются по значениям
Дамп только с данными содержит лишь строки, поэтому типы берутся из значений.
Строка отчета: no_schema
expressions in INSERT values
NULL
Конвертер, который не запускает базу данных, не может их вычислить.
Строка отчета: expression_value
types IntoSQL doesn't know
text
Тип text вмещает любое значение; измените тип после загрузки.
Строка отчета: unknown_type
text that isn't valid in its encoding
неверные байты заменяются символом замены
Текст в PostgreSQL должен быть корректным UTF-8.
Строка отчета: invalid_utf8_replaced
text decoded twice (ñ)
копируется как есть
Дамп содержит именно эти символы, поэтому они копируются; отчет на них указывает.
Строка отчета: mojibake_suspected
| В файле | В скрипте | Строка отчета |
|---|---|---|
| varchar(n), char(n), text | те же типыТе же типы с теми же длинами. | |
| numeric(p,s), numeric without a precision, NaN and Infinity | те же типы и значенияТот же тип: каждая цифра копируется так, как ее записал дамп. | |
| money | numeric(19,2)Запись money зависит от lc_monetary сервера, поэтому сумма хранится как число без символа валюты и загружается при любой локали целевой базы. | type_replaced |
| enum types | те же типы enum, создаются до таблицМетки сохраняют свой порядок. | |
| enum columns holding values outside their labels | text без проверкиТип отклонил бы эти значения, поэтому столбец имеет тип text и сохраняет их все. | enum_check_skipped |
| composite and range types the dump defines, extension types (citext, hstore, ltree, PostGIS) and multiranges | text с текстом PostgreSQLСкрипт не создает ни расширения, ни составные типы, поэтому каждое значение сохраняет текст, записанный PostgreSQL; после загрузки создайте тип и измените столбец. | type_replaced |
| citext | text, точное сравнениеСкрипт не создает расширение citext, поэтому эти столбцы сравнивают текст точно; после загрузки создайте его и верните столбцам прежний тип. | case_insensitive_collation |
| json, jsonb | те же типыjson хранит текст в исходном виде; jsonb хранит значения так, как их нормализовал сервер. | |
| timestamp with time zone | timestamptz, те же моментыКаждое значение сохраняет смещение, записанное дампом, поэтому момент один и тот же в любом часовом поясе. | |
| time, time with time zone | те же типыТе же типы, включая 24:00:00. | |
| infinity, -infinity and BC dates | сохраняетсяPostgreSQL хранит их как есть. | |
| NaN and Infinity in numeric, real and double precision | сохраняетсяPostgreSQL хранит их как есть. | |
| generated columns | те же генерируемые столбцыТа же формула, которую вычисляет целевая база. | |
| generated columns with functions IntoSQL doesn't write | обычный столбец со значениямиФормула, которую IntoSQL не может записать, оставляет обычный столбец со значениями из дампа и строку в отчете. | generated_not_translated |
| defaults with functions IntoSQL doesn't write | без значения по умолчаниюЗначение по умолчанию, которое IntoSQL не может записать, опускается и попадает в отчет. | default_not_translated |
| CHECK constraints with functions IntoSQL doesn't write | не создаетсяПроверка, которую IntoSQL не может записать, опускается и попадает в отчет. | check_skipped |
| CHECK ... NOT VALID | добавляется как NOT VALID после строкСтроки, которые были до нее, не проверялись, поэтому проверка добавляется после них и остается NOT VALID. | |
| gin, gist, brin and hash indexes, partial and expression indexes | не создаетсяIntoSQL пишет индексы b-tree по столбцам; остальные создайте заново после загрузки. | index_skipped |
| foreign keys to tables the dump doesn't create | не создаетсяКлюч не может ссылаться на таблицу, которой нет. | foreign_key_skipped |
| NOT NULL columns with values that become NULL | NOT NULL снимаетсяСтолбец, значения которого пришлось заменить на NULL, не может сохранить NOT NULL, иначе загрузка остановится. | not_null_relaxed |
| partitioned tables | одна таблица со строками всех секцийСтроки те же; при необходимости секционируйте таблицу заново. | partitions_dropped |
| views, functions, procedures, triggers, rules, policies, extensions and types other than enums | перечисляются в отчетеIntoSQL конвертирует таблицы и их строки; остальное перечислено, чтобы вы создали его заново. | not_converted_objects |
| dumps without CREATE TABLE (--data-only) | типы определяются по значениямДамп только с данными содержит лишь строки, поэтому типы берутся из значений. | no_schema |
| expressions in INSERT values | NULLКонвертер, который не запускает базу данных, не может их вычислить. | expression_value |
| types IntoSQL doesn't know | textТип text вмещает любое значение; измените тип после загрузки. | unknown_type |
| text that isn't valid in its encoding | неверные байты заменяются символом заменыТекст в PostgreSQL должен быть корректным UTF-8. | invalid_utf8_replaced |
| text decoded twice (ñ) | копируется как естьДамп содержит именно эти символы, поэтому они копируются; отчет на них указывает. | mojibake_suspected |
Загрузите скрипт в PostgreSQL
Скрипт создает таблицы, копирует строки, затем добавляет ключи, индексы и внешние ключи, поэтому загрузка идет быстро и останавливается на первой ошибке.
psql -v ON_ERROR_STOP=1 -d mydb -f postgresql.postgresql.sqlВнешние ключи добавляются как NOT VALID, а затем проверяются. Если строка ссылается на несуществующую строку, скрипт сообщает, какое ограничение нарушено, а не прерывается на полпути.
Для большого дампа сначала создайте базу данных и запустите скрипт через psql на той же машине, где работает сервер.
IntoSQL Pro загружает файл прямо в PostgreSQL из приложения для компьютера или командной строки, без написания скрипта.
Как создать дамп PostgreSQL для лучшего результата
Конвертер читает то, что есть в дампе. Эти параметры сохраняют в нем больше ваших данных:
- --format=plain, формат pg_dump по умолчанию, пишет SQL. Архив custom или directory (-Fc, -Fd) превращается в SQL командой pg_restore -f dump.sql, без сервера баз данных.
- --no-owner --no-privileges исключают роли и права, которые конвертер все равно пропускает, поэтому дамп получается меньше.
- pg_dumpall сохраняет все базы данных в один файл; имена таблиц каждой базы начинаются с ее имени, поэтому ничего не конфликтует.
Что не конвертируется
Представления, триггеры, процедуры, функции и другие объекты, написанные на собственном языке PostgreSQL, перечислены в отчете по имени и никогда не удаляются молча, чтобы вы могли проверить каждый на той версии PostgreSQL, в которую загружаете, прежде чем создать его заново.
Вопросы о переносе PostgreSQL между версиями
Нет ответа на ваш вопрос? Напишите нам через страницу контактов, и вам ответит человек. Страница контактов
Мой дамп загружается на сервер?
Нет. Конвертер работает в вашем браузере и читает дамп с диска по частям, поэтому он никогда не покидает ваш компьютер. Приложение для компьютера и командная строка тоже конвертируют на вашем компьютере.
Насколько большим может быть дамп?
Конвертер никогда не держит весь дамп в памяти: он читает файл дважды, по диапазонам, и пишет скрипт по ходу чтения. Дампы в несколько гигабайт конвертируются в браузере, в приложении для компьютера и в командной строке.
Читает ли он архивы pg_dump -Fc?
Не напрямую: архив custom - это двоичный формат. pg_restore -f dump.sql dump.backup превращает его в обычный SQL, который читает конвертер, без подключения к серверу. Получив архив, конвертер так и сообщает.
Из каких версий PostgreSQL может быть дамп?
Дампы, записанные pg_dump и pg_dumpall из PostgreSQL 10 и новее, со строками COPY или INSERT. Каждый тестовый дамп создан в PostgreSQL 13 и 18 и сверен с источником ячейка за ячейкой.
Сохраняются ли значения serial и identity?
Да. Столбцы serial и identity остаются столбцами identity, каждая строка сохраняет свой id, а каждый счетчик продолжается со значения, которого достигла последовательность в дампе.
Что происходит с массивами, enum и другими типами PostgreSQL?
Они остаются как есть: массивы, диапазоны, json и jsonb, битовые строки; исключение - money. Типы enum создаются заново со своими метками. Типы из расширений (citext, hstore, PostGIS) и составные типы становятся text, а отчет указывает, какие столбцы.
А функции, триггеры и представления?
Они перечислены в отчете по имени и не конвертируются, чтобы вы могли создать их заново, когда таблицы будут загружены. Проверки NOT VALID добавляются после строк и по-прежнему имеют статус NOT VALID.
На каких версиях PostgreSQL загружается скрипт?
PostgreSQL с 13 по 18, какой бы версией ни был записан дамп. Один и тот же скрипт загружается на каждой из них и останавливается на первой ошибке, если что-то пойдет не так.