Aller au contenu
Accueil IntoSQL

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.

Votre fichier
sqlshop_2024.sqlFichier d'exemple, 5,1 ko
Votre base de données

18 lignes converties, 8 corrections, aucune rejetée

Afficher

Tables de shop_2024.sqlDump MySQL 8.0.46 · écrit par mysqldump · utf8mb4

  • customers8 lignes3
    7 colonnes
    idbigint not null
    namevarchar(100) not null
    emailvarchar(150) not null
    countryvarchar(2) not null
    is_activeboolean not null
    signed_update
    created_attimestamptz(0) not null
  • orders10 lignes5
    9 colonnes
    idbigint not null
    customer_idbigint not null
    statustext not null
    totalnumeric(10,2) not null
    itemsinteger not null
    ordered_attimestamp(0) not null
    shipped_attimestamp(0)
    notevarchar(255)
    updated_attimestamptz(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

  1. "id" de customers est non signée ; elle est donc devenue bigint avec un CHECK qui interdit les valeurs négatives.
  2. "signed_up" de customers accepte maintenant NULL : certaines de ses valeurs ne pouvaient pas être stockées et sont NULL.
  3. 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.
  4. "customer_id" de orders est non signée ; elle est donc devenue bigint avec un CHECK qui interdit les valeurs négatives.
  5. "id" de orders est non signée ; elle est donc devenue bigint avec un CHECK qui interdit les valeurs négatives.
  6. "items" de orders est non signée ; elle est donc devenue integer avec un CHECK qui interdit les valeurs négatives.
  7. 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.
  8. "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.

Types de données de chaque paire

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.
La page MySQL vers PostgreSQL

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 :

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.