Convertir une base de données en une autre
Déposez un dump de mysqldump, mariadb-dump, pg_dump, SSMS, SQL Developer ou SQLcl, ou un fichier .db SQLite, et téléchargez un script pour PostgreSQL, MySQL, MariaDB, SQLite, SQL Server ou Oracle avec les mêmes tables, clés, index et données. Chaque changement figure dans un rapport, et le dump ne quitte jamais votre ordinateur.
18 lignes converties, 8 corrections, aucune rejetée
Tables de shop_2024.sqlDump MySQL 8.0.46 · écrit par mysqldump · utf8mb4
customers8 lignes3
7 colonnes 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 lignes5
9 colonnes 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();
Corrections
- "id" de customers est non signée ; elle est donc devenue bigint avec un CHECK qui interdit les valeurs négatives.
- "signed_up" de customers accepte maintenant NULL : certaines de ses valeurs ne pouvaient pas être stockées et sont NULL.
- La valeur par défaut de "signed_up" dans customers, 0000‑00‑00, n'est pas une date acceptée par PostgreSQL ; la colonne n'a donc pas de valeur par défaut.
- "customer_id" de orders est non signée ; elle est donc devenue bigint avec un CHECK qui interdit les valeurs négatives.
- "id" de orders est non signée ; elle est donc devenue bigint avec un CHECK qui interdit les valeurs négatives.
- "items" de orders est non signée ; elle est donc devenue integer avec un CHECK qui interdit les valeurs négatives.
- 1 ligne de "status" dans orders contient la valeur vide que MySQL stocke pour les entrées invalides ; la contrainte CHECK de ses valeurs l'autorise.
- "updated_at" de orders passe à l'heure actuelle à chaque mise à jour ; dans PostgreSQL, un déclencheur s'en charge.
À vérifier
- 1 valeur dans "signed_up" de customers est une date zéro ou impossible, comme 0000‑00‑00, que PostgreSQL ne peut pas stocker ; elle est donc NULL. Si ces dates ont un sens, remplacez-les dans la source par de vraies dates avant le dump.
- 1 valeur dans "shipped_at" de orders est une date zéro ou impossible, comme 0000‑00‑00 00:00:00, que PostgreSQL ne peut pas stocker ; elle est donc NULL. Si ces dates ont un sens, remplacez-les dans la source par de vraies dates avant le dump.
Votre fichier est converti sur cet ordinateur et n'est jamais envoyé.
Autres exemples :
Toutes les paires de bases de données
Les lignes sont la base de données d'où vient le dump, les colonnes celle à laquelle le script est destiné. Chaque paire a sa propre page avec le convertisseur préparé pour elle, les règles qu'il applique et la façon de charger le script.
- MySQL
- MariaDB
- PostgreSQL
- SQL Server
- SQLite
- Oracle
| de ↓ vers → | PostgreSQL | MySQL | MariaDB | SQLite | SQL Server | Oracle |
|---|---|---|---|---|---|---|
| MySQL | MySQL vers PostgreSQL | MySQL vers MySQL | MySQL vers MariaDB | MySQL vers SQLite | MySQL vers SQL Server | MySQL vers Oracle |
| MariaDB | MariaDB vers PostgreSQL | MariaDB vers MySQL | MariaDB vers MariaDB | MariaDB vers SQLite | MariaDB vers SQL Server | MariaDB vers Oracle |
| PostgreSQL | PostgreSQL vers PostgreSQL | PostgreSQL vers MySQL | PostgreSQL vers MariaDB | PostgreSQL vers SQLite | PostgreSQL vers SQL Server | PostgreSQL vers Oracle |
| SQL Server | SQL Server vers PostgreSQL | SQL Server vers MySQL | SQL Server vers MariaDB | SQL Server vers SQLite | SQL Server vers SQL Server | SQL Server vers Oracle |
| SQLite | SQLite vers PostgreSQL | SQLite vers MySQL | SQLite vers MariaDB | SQLite vers SQLite | SQLite vers SQL Server | SQLite vers Oracle |
| Oracle | Oracle vers PostgreSQL | Oracle vers MySQL | Oracle vers MariaDB | Oracle vers SQLite | Oracle vers SQL Server | Oracle vers Oracle |
Ce qui est conservé et ce qui est signalé
Le convertisseur lit le dump lui-même, sans serveur de base de données, et écrit le script à partir de son contenu. La page de chaque paire liste les règles appliquées, entre 25 et 67 par paire, avec la ligne de rapport que chacune écrit.
Conservé dans le script
- Tables et colonnes, chacune avec le type le plus proche de la cible, sa longueur et sa précision.
- Clés primaires, uniques et étrangères, index et valeurs par défaut.
- Colonnes AUTO_INCREMENT, identity et serial, avec l'id de chaque ligne et le compteur qui reprend là où le dump l'a laissé.
- Chaque ligne, avec les dates, décimaux, textes et valeurs binaires tels que le dump les contient.
Listé dans le rapport
- Les valeurs que la cible ne peut pas stocker telles quelles, comme une date 0000-00-00 dans PostgreSQL, avec la colonne et leur nombre.
invalid_date_null - Les types que la cible n'a pas, comme ENUM ou INET6, avec le type choisi pour chacun.
type_replaced - Vues, triggers, procédures, fonctions et événements, par nom : ils sont écrits dans le propre langage de chaque base, donc ils ne sont pas convertis.
not_converted_objects - Le texte qui n'est pas valide dans son jeu de caractères, et les dumps qui ont déjà perdu leurs caractères sur 4 octets.
invalid_utf8_replaced
Comparé à pgloader
Les mêmes dumps, convertis et chargés par IntoSQL et par pgloader 3.6.7 sur une même machine (un i9-10900K à 10 cœurs avec un SATA SSD), en octobre 2026.
- Une colonne TINYINT(1) contenant 2, -1 et -5 : pgloader charge true pour chacune, sans avertissement. IntoSQL garde les nombres et le rapport explique pourquoi.
- Un dump avec une valeur par défaut 'it's', une table dont le nom contient un accent grave, un ENUM contenant la valeur vide et un TIME de plus de 24 heures : pgloader s'arrête. IntoSQL le convertit et le charge.
- Ce que pgloader charge a perdu ses clés primaires, uniques et étrangères, et ses identités. IntoSQL les garde toutes.
- Un dump de 5.3 GB et 30 millions de lignes : pgloader exige qu'il soit d'abord restauré dans un MySQL en marche, ce qui prend 18 minutes, puis manque de mémoire avec ses réglages par défaut. IntoSQL convertit le dump en 10 secondes, et psql charge le script en 3 minutes environ.
- Sur 476 dumps de MySQL 5.5 à 9 et de MariaDB 10.3 à 12, chargés dans PostgreSQL 13 et 18 : aucune erreur de chargement, et aucune valeur modifiée sans une ligne dans le rapport.
Exporter la base de données que vous avez
Le convertisseur lit un fichier, pas un serveur en marche. Chaque base de données en écrit un avec ses propres outils :
MySQL
Un dump de mysqldump, mysqlpump, phpMyAdmin ou Adminer, en .sql ou .sql.gz. --default-character-set=utf8mb4 --hex-blob --routines --triggers --events conservent le plus.
Guide de migration de MySQL vers PostgreSQLMariaDB
Un dump de mariadb-dump, mysqldump, phpMyAdmin ou Adminer, en .sql ou .sql.gz, avec les mêmes options que MySQL.
Guide de migration de MariaDB vers PostgreSQLPostgreSQL
Un dump texte de pg_dump ou pg_dumpall. Une archive custom (-Fc) devient un dump texte avec pg_restore -f dump.sql, sans serveur.
Guide de migration de PostgreSQL vers MySQLSQL Server
Le script qu'écrit Generate Scripts de SSMS, avec Types of data to script réglé sur Schema and data. dbatools et mssql-scripter écrivent la même chose.
Guide de migration de SQL Server vers PostgreSQLSQLite
Le fichier de base lui-même (.db, .sqlite, .sqlite3), ou le SQL qu'écrit sqlite3 app.db .dump.
Guide de migration de SQLite vers PostgreSQLOracle
Le fichier .sql qu'écrit Database Export de SQL Developer ou SQLcl, avec DDL et Insert. Un fichier .dmp de exp ou expdp doit d'abord être importé puis exporté à nouveau.
Guide de migration de Oracle vers PostgreSQL
Questions sur la migration de base de données
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.
De quelles versions le dump peut-il venir ?
MySQL 5.5 à 9, MariaDB 10.3 à 12, PostgreSQL 10 et suivants, SQL Server 2017 et suivants, SQLite 3.0 et suivants, et Oracle 11g et suivants. La page de chaque paire indique sur quelles versions son script se charge.
Faut-il un serveur de base de données en marche ?
Non. Le convertisseur lit le fichier de dump lui-même, donc la base source n'a pas besoin de tourner. Le script se charge avec le client de la cible, comme psql, mysql ou sqlcmd.
Qu'est-ce qui n'est pas converti ?
Les vues, triggers, procédures stockées, fonctions et événements sont écrits dans le propre langage de chaque base, donc ils sont listés par nom dans le rapport. Les tables, clés, index et lignes sont tous dans le script.
Peut-il charger le script directement dans ma base de données ?
L'application de bureau et la commande intosql load écrivent directement dans SQLite gratuitement, et dans PostgreSQL, MySQL et MariaDB avec IntoSQL Pro. Pour SQL Server et Oracle, exécutez le script avec sqlcmd ou sqlplus.