Конвертируйте базу данных в другую базу данных
Перетащите дамп из mysqldump, mariadb-dump, pg_dump, SSMS, SQL Developer или SQLcl либо файл SQLite .db и скачайте один скрипт для PostgreSQL, MySQL, MariaDB, SQLite, SQL Server или Oracle с теми же таблицами, ключами, индексами и данными. Каждое изменение указано в отчете, а дамп никогда не покидает ваш компьютер.
18 строк конвертировано, 8 исправлений, ни одна не отклонена
Таблицы в shop_2024.sqlДамп MySQL 8.0.46 · создан программой mysqldump · utf8mb4
customers8 строк3
7 столбцов id bigint not null name varchar(100) not null email varchar(150) not null country varchar(2) not null is_active boolean not null signed_up date created_at timestamptz(0) not null orders10 строк5
9 столбцов id bigint not null customer_id bigint not null status text not null total numeric(10,2) not null items integer not null ordered_at timestamp(0) not null shipped_at timestamp(0) note varchar(255) updated_at timestamptz(0) not null
-- Written by IntoSQL from a MySQL 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 TABLE customers (
id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL,
name varchar(100) NOT NULL,
email varchar(150) NOT NULL,
country varchar(2) DEFAULT 'US' NOT NULL,
is_active boolean DEFAULT true NOT NULL,
signed_up date,
created_at timestamptz(0) DEFAULT CURRENT_TIMESTAMP NOT NULL,
CONSTRAINT customers_id_check CHECK (id >= 0)
);
CREATE TABLE orders (
id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL,
customer_id bigint NOT NULL,
status text DEFAULT 'pending' NOT NULL,
total numeric(10,2) NOT NULL,
items integer DEFAULT 1 NOT NULL,
ordered_at timestamp(0) NOT NULL,
shipped_at timestamp(0),
note varchar(255),
updated_at timestamptz(0) DEFAULT CURRENT_TIMESTAMP NOT NULL,
CONSTRAINT orders_id_check CHECK (id >= 0),
CONSTRAINT orders_customer_id_check CHECK (customer_id >= 0),
CONSTRAINT orders_status_check CHECK (status IN ('pending', 'paid', 'shipped', 'cancelled', '')),
CONSTRAINT orders_items_check CHECK (items >= 0)
);
COPY customers (id, name, email, country, is_active, signed_up, created_at) FROM stdin;
1 Ana Martínez ana@example.com MX t 2023-01-15 2023-01-15 10:24:00+00:00
2 Zoë Müller zoe@example.de DE t 2023-02-03 2023-02-03 08:11:42+00:00
3 José Peña jose@example.es ES f 2023-03-21 2023-03-21 19:05:17+00:00
4 李雷 lilei@example.cn CN t 2023-05-09 2023-05-09 02:40:00+00:00
5 Noah O'Brien noah@example.ie IE t \N 2023-06-30 14:00:00+00:00
6 Amélie Laurent amelie@example.fr FR t 2024-01-02 2024-01-02 09:30:00+00:00
7 Ravi Patel ravi@example.in IN f 2024-02-29 2024-02-29 23:59:59+00:00
8 Sofia Rossi 🌻 sofia@example.it IT t 2024-04-12 2024-04-12 12:12:12+00:00
\.
COPY orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, updated_at) FROM stdin;
1 1 shipped 129.90 3 2024-03-01 10:00:00 2024-03-02 16:30:00 \N 2024-03-02 16:30:00+00:00
2 2 paid 54.00 1 2024-03-02 11:15:00 \N Gift wrap 🎁 2024-03-02 11:20:00+00:00
3 1 cancelled 12.50 1 2024-03-03 09:45:00 \N Customer changed their mind 2024-03-03 10:00:00+00:00
4 4 shipped 980.00 12 2024-03-05 02:10:00 2024-03-07 08:00:00 请小心轻放 2024-03-07 08:00:00+00:00
5 5 pending 45.75 2 2024-03-08 17:20:00 \N Leave at the door; ring twice 2024-03-08 17:20:00+00:00
6 6 shipped 310.40 5 2024-03-10 13:00:00 2024-03-11 09:00:00 Fragile: "glass" 2024-03-11 09:00:00+00:00
7 8 paid 76.20 2 2024-03-11 18:45:00 \N \N 2024-03-11 18:46:00+00:00
8 2 19.99 1 2024-03-12 08:00:00 \N Status lost in an old import 2024-03-12 08:00:00+00:00
9 3 shipped 64.00 2 2024-03-14 15:30:00 \N Shipping date never recorded 2024-03-15 10:00:00+00:00
10 7 paid 1499.00 1 2024-03-15 21:05:00 \N C:\\Users\\ravi\\invoice.pdf 2024-03-15 21:05:00+00:00
\.
-- Keys, indexes and constraints, after the rows so each builds once.
CREATE UNIQUE INDEX customers_pkey ON customers (id);
CREATE UNIQUE INDEX customers_uq_email ON customers (email);
CREATE UNIQUE INDEX orders_pkey ON orders (id);
CREATE INDEX orders_idx_customer ON orders (customer_id);
CREATE INDEX orders_idx_status_date ON orders (status, ordered_at);
ALTER TABLE customers ADD CONSTRAINT customers_pkey PRIMARY KEY USING INDEX customers_pkey;
ALTER TABLE customers ADD CONSTRAINT customers_uq_email UNIQUE USING INDEX customers_uq_email;
ALTER TABLE orders ADD CONSTRAINT orders_pkey PRIMARY KEY USING INDEX orders_pkey;
ALTER TABLE orders ADD CONSTRAINT fk_orders_customer FOREIGN KEY (customer_id) REFERENCES customers (id) NOT VALID;
DO $f$ BEGIN
ALTER TABLE orders VALIDATE CONSTRAINT fk_orders_customer;
EXCEPTION WHEN foreign_key_violation THEN
RAISE WARNING 'foreign key % has rows without a parent: it stays NOT VALID, and new rows are checked', 'fk_orders_customer';
END $f$;
SELECT setval(pg_get_serial_sequence('customers', 'id'), LEAST(GREATEST(COALESCE((SELECT max(id) FROM customers)::numeric, 0) + 1, 1001), 9223372036854775807)::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), 9223372036854775807)::bigint, false);
CREATE FUNCTION orders_updated_at_on_update() RETURNS trigger LANGUAGE plpgsql AS $f$
BEGIN
IF NEW IS DISTINCT FROM OLD AND NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at THEN
NEW.updated_at := CURRENT_TIMESTAMP;
END IF;
RETURN NEW;
END
$f$;
CREATE TRIGGER orders_updated_at_on_update BEFORE UPDATE ON orders FOR EACH ROW EXECUTE FUNCTION orders_updated_at_on_update();
Исправления
- Столбец "id" таблицы customers беззнаковый, поэтому он стал bigint с проверкой, что значение не отрицательное.
- Столбец "signed_up" таблицы customers теперь допускает NULL: часть его значений нельзя было сохранить, и они записаны как NULL.
- Значение по умолчанию столбца "signed_up" таблицы customers, 0000‑00‑00, не является датой, которую принимает PostgreSQL, поэтому у столбца его нет.
- Столбец "customer_id" таблицы orders беззнаковый, поэтому он стал bigint с проверкой, что значение не отрицательное.
- Столбец "id" таблицы orders беззнаковый, поэтому он стал bigint с проверкой, что значение не отрицательное.
- Столбец "items" таблицы orders беззнаковый, поэтому он стал integer с проверкой, что значение не отрицательное.
- В 1 строке столбца "status" таблицы orders пустое значение, которое MySQL записывает вместо недопустимых; проверка значений его допускает.
- Столбец "updated_at" таблицы orders получает текущее время при каждом обновлении; в PostgreSQL это делает триггер.
Требует проверки
- В "signed_up" таблицы customers 1 значение - нулевая или невозможная дата, например 0000‑00‑00; PostgreSQL не может их хранить, поэтому записан NULL. Если эти даты что-то значат, замените их в источнике настоящими до создания дампа.
- В "shipped_at" таблицы orders 1 значение - нулевая или невозможная дата, например 0000‑00‑00 00:00:00; PostgreSQL не может их хранить, поэтому записан NULL. Если эти даты что-то значат, замените их в источнике настоящими до создания дампа.
Файл конвертируется на этом компьютере и никуда не загружается.
Другие примеры:
Все пары баз данных
Строки - база данных, из которой взят дамп, столбцы - база данных, для которой пишется скрипт. У каждой пары своя страница с настроенным для нее конвертером, правилами, которые он применяет, и описанием загрузки скрипта.
- MySQL
- MariaDB
- PostgreSQL
- SQL Server
- SQLite
- Oracle
| из ↓ в → | PostgreSQL | MySQL | MariaDB | SQLite | SQL Server | Oracle |
|---|---|---|---|---|---|---|
| MySQL | MySQL в PostgreSQL | MySQL в MySQL | MySQL в MariaDB | MySQL в SQLite | MySQL в SQL Server | MySQL в Oracle |
| MariaDB | MariaDB в PostgreSQL | MariaDB в MySQL | MariaDB в MariaDB | MariaDB в SQLite | MariaDB в SQL Server | MariaDB в Oracle |
| PostgreSQL | PostgreSQL в PostgreSQL | PostgreSQL в MySQL | PostgreSQL в MariaDB | PostgreSQL в SQLite | PostgreSQL в SQL Server | PostgreSQL в Oracle |
| SQL Server | SQL Server в PostgreSQL | SQL Server в MySQL | SQL Server в MariaDB | SQL Server в SQLite | SQL Server в SQL Server | SQL Server в Oracle |
| SQLite | SQLite в PostgreSQL | SQLite в MySQL | SQLite в MariaDB | SQLite в SQLite | SQLite в SQL Server | SQLite в Oracle |
| Oracle | Oracle в PostgreSQL | Oracle в MySQL | Oracle в MariaDB | Oracle в SQLite | Oracle в SQL Server | Oracle в Oracle |
Что сохраняется и о чем сообщается
Конвертер сам читает дамп, без сервера базы данных, и пишет скрипт по его содержимому. Страница каждой пары перечисляет правила, которые он применяет, от 25 до 67 на пару, со строкой отчета, которую пишет каждое правило.
Сохраняется в скрипте
- Таблицы и столбцы, каждый с ближайшим типом, который есть в целевой базе, с его длиной и точностью.
- Первичные, уникальные и внешние ключи, индексы и значения по умолчанию.
- Столбцы AUTO_INCREMENT, identity и serial: id каждой строки сохраняется, а счетчик продолжается с того места, где его оставил дамп.
- Каждая строка, с датами, десятичными числами, текстом и двоичными значениями в том виде, в каком они есть в дампе.
Указывается в отчете
- Значения, которые целевая база не может хранить как есть, например дата 0000-00-00 в PostgreSQL, со столбцом и количеством.
invalid_date_null - Типы, которых нет в целевой базе, например ENUM или INET6, с типом, которым стал каждый.
type_replaced - Представления, триггеры, процедуры, функции и события, по имени: они написаны на собственном языке каждой базы данных, поэтому не конвертируются.
not_converted_objects - Текст, недопустимый в своей кодировке, и дампы, которые уже потеряли 4-байтовые символы.
invalid_utf8_replaced
Сравнение с pgloader
Одни и те же дампы, конвертированные и загруженные IntoSQL и pgloader 3.6.7 на одной машине (10-ядерный i9-10900K с SATA SSD) в октябре 2026 года.
- Столбец TINYINT(1) со значениями 2, -1 и -5: pgloader загружает для каждого true, без предупреждения. IntoSQL сохраняет числа, а отчет объясняет почему.
- Дамп со значением по умолчанию 'it's', таблицей с обратной кавычкой в имени, ENUM с пустым значением и TIME больше 24 часов: pgloader останавливается. IntoSQL конвертирует и загружает его.
- В том, что загружает pgloader, теряются первичные, уникальные и внешние ключи и identity. IntoSQL сохраняет их все.
- Дамп 5.3 GB на 30 миллионов строк: pgloader требует сначала восстановить его в работающий MySQL, что занимает 18 минут, а затем с настройками по умолчанию ему не хватает памяти. IntoSQL конвертирует дамп за 10 секунд, а psql загружает скрипт примерно за 3 минуты.
- 476 дампов из MySQL с 5.5 по 9 и MariaDB с 10.3 по 12, загруженных в PostgreSQL 13 и 18: ни одной ошибки загрузки, и ни одно значение не изменилось без строки в отчете.
Экспортируйте вашу базу данных
Конвертер читает файл, а не работающий сервер. Каждая база данных пишет его своими инструментами:
MySQL
Дамп из mysqldump, mysqlpump, phpMyAdmin или Adminer в формате .sql или .sql.gz. Параметры --default-character-set=utf8mb4 --hex-blob --routines --triggers --events сохраняют больше всего.
Руководство по миграции MySQL в PostgreSQLMariaDB
Дамп из mariadb-dump, mysqldump, phpMyAdmin или Adminer в формате .sql или .sql.gz, с теми же параметрами, что и для MySQL.
Руководство по миграции MariaDB в PostgreSQLPostgreSQL
Обычный дамп из pg_dump или pg_dumpall. Архив в формате custom (-Fc) превращается в такой дамп командой pg_restore -f dump.sql, без сервера.
Руководство по миграции PostgreSQL в MySQLSQL Server
Скрипт, который пишет Generate Scripts в SSMS, с параметром Types of data to script, равным Schema and data. dbatools и mssql-scripter пишут то же самое.
Руководство по миграции SQL Server в PostgreSQLSQLite
Сам файл базы данных (.db, .sqlite, .sqlite3) или SQL, который пишет sqlite3 app.db .dump.
Руководство по миграции SQLite в PostgreSQLOracle
Файл .sql, который пишет Database Export в SQL Developer или SQLcl, с командами DDL и Insert. Файл .dmp из exp или expdp нужно сначала импортировать и экспортировать заново.
Руководство по миграции Oracle в PostgreSQL
Вопросы о миграции базы данных
Нет ответа на ваш вопрос? Напишите нам через страницу контактов, и вам ответит человек. Страница контактов
Мой дамп загружается на сервер?
Нет. Конвертер работает в вашем браузере и читает дамп с диска по частям, поэтому он никогда не покидает ваш компьютер. Приложение для компьютера и командная строка тоже конвертируют на вашем компьютере.
Насколько большим может быть дамп?
Конвертер никогда не держит весь дамп в памяти: он читает файл дважды, по диапазонам, и пишет скрипт по ходу чтения. Дампы в несколько гигабайт конвертируются в браузере, в приложении для компьютера и в командной строке.
Из каких версий может быть дамп?
MySQL с 5.5 по 9, MariaDB с 10.3 по 12, PostgreSQL 10 и новее, SQL Server 2017 и новее, SQLite 3.0 и новее и Oracle 11g и новее. Страница каждой пары указывает, на каких версиях загружается ее скрипт.
Нужен ли работающий сервер базы данных?
Нет. Конвертер сам читает файл дампа, поэтому исходная база данных нигде не должна работать. Скрипт загружается собственным клиентом целевой базы, например psql, mysql или sqlcmd.
Что не конвертируется?
Представления, триггеры, хранимые процедуры, функции и события написаны на собственном языке каждой базы данных, поэтому вместо этого они перечислены в отчете по имени. Таблицы, ключи, индексы и строки все есть в скрипте.
Может ли он загрузить скрипт прямо в мою базу данных?
Приложение для компьютера и команда intosql load пишут прямо в SQLite бесплатно, а в PostgreSQL, MySQL и MariaDB с IntoSQL Pro. Для SQL Server и Oracle запустите скрипт через sqlcmd или sqlplus.