Aller au contenu
Accueil IntoSQL

Convertir MySQL en SQLite

Déposez un dump de mysqldump, mariadb-dump, mysqlpump, phpMyAdmin ou Adminer, en .sql ou .sql.gz, et téléchargez un script SQLite avec les mêmes tables, clés, index et données. Chaque valeur que SQLite ne peut pas contenir telle quelle, et chaque objet qu'il ne reprend pas, est listé dans le rapport.

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
    idINTEGER not null
    nameVARCHAR(100) not null
    emailVARCHAR(150) not null
    countryVARCHAR(2) not null
    is_activeINTEGER not null
    signed_upDATE
    created_atTIMESTAMP not null
  • orders10 lignes5
    9 colonnes
    idINTEGER not null
    customer_idINTEGER not null
    statusTEXT not null
    totalDECIMAL(10,2) not null
    itemsINTEGER not null
    ordered_atDATETIME not null
    shipped_atDATETIME
    noteVARCHAR(255)
    updated_atTIMESTAMP not null
-- Written by IntoSQL from a MySQL dump. Load it with: sqlite3 -bail <database> < <file>
PRAGMA foreign_keys = OFF;
PRAGMA synchronous = OFF;
BEGIN;

CREATE TABLE customers ( -- People who bought at least once
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(150) NOT NULL,
    country VARCHAR(2) DEFAULT 'US' NOT NULL,
    is_active INTEGER DEFAULT 1 NOT NULL,
    signed_up DATE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
    CONSTRAINT customers_id_check CHECK (id >= 0)
);

CREATE TABLE orders (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    customer_id INTEGER NOT NULL,
    status TEXT DEFAULT 'pending' NOT NULL,
    total DECIMAL(10,2) NOT NULL,
    items INTEGER DEFAULT 1 NOT NULL,
    ordered_at DATETIME NOT NULL,
    shipped_at DATETIME,
    note VARCHAR(255),
    updated_at TIMESTAMP 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),
    CONSTRAINT fk_orders_customer FOREIGN KEY (customer_id) REFERENCES customers (id)
);

INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(1,'Ana Martínez','ana@example.com','MX',1,'2023-01-15','2023-01-15 10:24:00'),
(2,'Zoë Müller','zoe@example.de','DE',1,'2023-02-03','2023-02-03 08:11:42'),
(3,'José Peña','jose@example.es','ES',0,'2023-03-21','2023-03-21 19:05:17'),
(4,'李雷','lilei@example.cn','CN',1,'2023-05-09','2023-05-09 02:40:00'),
(5,'Noah O''Brien','noah@example.ie','IE',1,NULL,'2023-06-30 14:00:00'),
(6,'Amélie Laurent','amelie@example.fr','FR',1,'2024-01-02','2024-01-02 09:30:00'),
(7,'Ravi Patel','ravi@example.in','IN',0,'2024-02-29','2024-02-29 23:59:59'),
(8,'Sofia Rossi 🌻','sofia@example.it','IT',1,'2024-04-12','2024-04-12 12:12:12');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, updated_at) VALUES
(1,1,'shipped',129.90,3,'2024-03-01 10:00:00','2024-03-02 16:30:00',NULL,'2024-03-02 16:30:00'),
(2,2,'paid',54.00,1,'2024-03-02 11:15:00',NULL,'Gift wrap 🎁','2024-03-02 11:20:00'),
(3,1,'cancelled',12.50,1,'2024-03-03 09:45:00',NULL,'Customer changed their mind','2024-03-03 10: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'),
(5,5,'pending',45.75,2,'2024-03-08 17:20:00',NULL,'Leave at the door; ring twice','2024-03-08 17:20: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'),
(7,8,'paid',76.20,2,'2024-03-11 18:45:00',NULL,NULL,'2024-03-11 18:46:00'),
(8,2,'',19.99,1,'2024-03-12 08:00:00',NULL,'Status lost in an old import','2024-03-12 08:00:00'),
(9,3,'shipped',64.00,2,'2024-03-14 15:30:00',NULL,'Shipping date never recorded','2024-03-15 10:00:00'),
(10,7,'paid',1499.00,1,'2024-03-15 21:05:00',NULL,'C:\Users\ravi\invoice.pdf','2024-03-15 21:05:00');

-- Indexes, triggers and counters, after the rows so each index builds once.
CREATE UNIQUE INDEX customers_uq_email ON customers (email);
CREATE INDEX orders_idx_customer ON orders (customer_id);
CREATE INDEX orders_idx_status_date ON orders (status, ordered_at);
UPDATE sqlite_sequence SET seq = max(seq, 1000) WHERE name = 'customers';
INSERT INTO sqlite_sequence (name, seq) SELECT 'customers', 1000 WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = 'customers');
UPDATE sqlite_sequence SET seq = max(seq, 5000) WHERE name = 'orders';
INSERT INTO sqlite_sequence (name, seq) SELECT 'orders', 5000 WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = 'orders');
CREATE TRIGGER orders_updated_at_on_update AFTER UPDATE ON orders FOR EACH ROW WHEN NEW.updated_at IS OLD.updated_at AND (NEW.id IS NOT OLD.id OR NEW.customer_id IS NOT OLD.customer_id OR NEW.status IS NOT OLD.status OR NEW.total IS NOT OLD.total OR NEW.items IS NOT OLD.items OR NEW.ordered_at IS NOT OLD.ordered_at OR NEW.shipped_at IS NOT OLD.shipped_at OR NEW.note IS NOT OLD.note)
BEGIN
    UPDATE orders SET updated_at = CURRENT_TIMESTAMP WHERE rowid = NEW.rowid;
END;
COMMIT;

-- Rows whose foreign key finds no parent, if any: the load doesn't stop for them.
PRAGMA foreign_key_check;

Corrections

  1. "id" de customers est non signée ; elle est donc devenue INTEGER 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 SQLite ; la colonne n'a donc pas de valeur par défaut.
  4. "customer_id" de orders est non signée ; elle est donc devenue INTEGER avec un CHECK qui interdit les valeurs négatives.
  5. "id" de orders est non signée ; elle est donc devenue INTEGER 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 SQLite, 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 SQLite 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 SQLite 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 :

Ce qui change de MySQL à SQLite

Chaque ligne est une règle appliquée par le convertisseur, avec la ligne de rapport qu'il écrit quand la règle change quelque chose dans vos données.

  • TINYINT(1), BOOL

    INTEGER avec les valeurs telles quelles

    SQLite n'a pas de type booléen ; vrai et faux sont les entiers 1 et 0, donc chaque valeur garde son sens.

  • UNSIGNED integers

    INTEGER avec un CHECK qui interdit les négatifs ; BIGINT UNSIGNED avec des valeurs au-delà de 2^63-1 devient TEXT

    Les entiers SQLite font 64 bits et sont signés. Le CHECK écarte les valeurs négatives comme le faisait MySQL ; les valeurs hors de la plage signée sont gardées en texte pour ne perdre aucun chiffre.

    Ligne du rapport: unsigned_widened

  • ZEROFILL and display widths

    supprimé

    Le remplissage par des zéros est une façon d'afficher un nombre, pas une partie du nombre. Les nombres sont conservés ; formatez-les à la lecture si le remplissage compte.

    Ligne du rapport: zerofill_dropped

  • FLOAT(M,D)

    REAL, sans l'échelle

    Les flottants SQLite n'ont pas d'échelle fixe. Les valeurs stockées sont copiées telles quelles.

    Ligne du rapport: float_scale_dropped

  • DECIMAL(p,s)

    DECIMAL(p,s) jusqu'à 15 chiffres ; TEXT au-delà

    SQLite garde environ 15 chiffres significatifs dans un nombre. Les décimaux plus larges sont gardés en texte pour que chaque chiffre reste exact.

    Ligne du rapport: decimal_as_text

  • BIT(1), BIT(n)

    INTEGER avec la valeur des bits ; BIT(64) en chiffres TEXT

    Un champ de bits est stocké comme le nombre que forment ses bits. Le bit de poids fort d'un BIT(64) ne tient pas dans un entier signé, donc son nombre est gardé en texte.

  • zero, partial or impossible dates (0000-00-00, 2024-02-30)

    NULL

    Les fonctions de date de SQLite ne lisent que de vraies dates du calendrier. Elles deviennent NULL et le rapport les compte, comme pour toutes les autres bases de données.

    Ligne du rapport: invalid_date_null

  • NOT NULL columns with values that become NULL

    NOT NULL retiré

    Une colonne dont des valeurs ont dû devenir NULL ne peut pas garder NOT NULL, sinon le chargement s'arrêterait.

    Ligne du rapport: not_null_relaxed

  • DEFAULT '0000-00-00'

    aucune valeur par défaut

    Une valeur par défaut qui n'est pas une vraie date est omise plutôt que remplacée par une date inventée.

    Ligne du rapport: zero_date_default

  • TIME

    texte TIME tel que MySQL l'écrit, durées comprises

    SQLite garde les heures en texte, donc les durées de plus d'un jour ou négatives sont gardées exactement.

  • YEAR

    INTEGER avec un CHECK de sa plage

    SQLite n'a pas de type année ; le CHECK garde les mêmes valeurs que MySQL autorise.

  • CHAR(n), VARCHAR(n)

    VARCHAR(n), non appliqué

    SQLite garde le type déclaré pour les outils mais ne limite pas la longueur ; les valeurs sont celles que MySQL renvoie.

  • DATETIME

    DATETIME en texte ISO 8601

    SQLite stocke les dates en texte que ses fonctions de date savent lire.

  • TIMESTAMP

    TIMESTAMP en texte ISO 8601 en UTC ; le fuseau indiqué par le dump, UTC s'il n'en indique aucun

    Un TIMESTAMP est un instant, écrit en UTC. Les dumps indiquent le fuseau dans lequel ils l'ont écrit (mysqldump écrit en UTC) ; sinon, les valeurs sont lues en UTC et le rapport le signale.

    Ligne du rapport: timestamp_zone_assumed

  • ENUM

    TEXT avec un CHECK de ses valeurs

    Un texte avec une contrainte CHECK garde les mêmes valeurs.

  • ENUM holding '' (MySQL's error value)

    la valeur vide autorisée par le CHECK

    MySQL stocke une chaîne vide quand une valeur invalide entre dans un ENUM avec un mode SQL permissif. Ces lignes sont conservées et la contrainte CHECK les autorise.

    Ligne du rapport: enum_invalid_value

  • ENUM holding values outside its list

    pas de CHECK

    Les valeurs absentes de la liste feraient échouer la contrainte CHECK, qui n'est donc pas créée.

    Ligne du rapport: enum_check_skipped

  • SET

    TEXT tel que MySQL l'écrit ('a,b')

    SQLite n'a pas de tableaux ; le texte est celui que MySQL renvoie.

  • JSON

    TEXT

    Les fonctions JSON de SQLite lisent le JSON depuis du texte. Une colonne déclarée JSON transformerait "123" en nombre, elle est donc en TEXT.

  • NUL bytes in text

    conservé

    Le texte SQLite peut contenir un octet NUL, donc la valeur est copiée telle quelle.

  • text that isn't valid in its character set

    les octets invalides deviennent le caractère de remplacement

    Le texte SQLite est en UTF-8 ; ses fonctions lisent mal les octets qui ne le sont pas.

    Ligne du rapport: invalid_utf8_replaced

  • text decoded twice (ñ)

    copié tel quel

    Le dump contient exactement ces caractères, ils sont donc copiés ; le rapport les signale.

    Ligne du rapport: mojibake_suspected

  • AUTO_INCREMENT

    INTEGER PRIMARY KEY AUTOINCREMENT, avec le compteur placé après les identifiants copiés

    SQLite compte une clé primaire entière de type entier. AUTOINCREMENT empêche de réutiliser les identifiants, comme MySQL, et le compteur reprend après le plus élevé ou après l'AUTO_INCREMENT du dump, selon le plus grand.

  • AUTO_INCREMENT on part of a key or outside one

    INTEGER sans compteur

    SQLite ne compte qu'une colonne qui forme toute la clé primaire ; la colonne garde donc ses valeurs et les nouvelles lignes doivent fournir les leurs.

    Ligne du rapport: identity_without_counter

  • ON UPDATE CURRENT_TIMESTAMP

    un déclencheur AFTER UPDATE

    Le déclencheur met la colonne à l'heure actuelle quand une ligne change et que la mise à jour ne l'a pas définie, comme le fait MySQL.

    Ligne du rapport: on_update_trigger

  • generated columns

    GENERATED ALWAYS AS, VIRTUAL ou STORED comme dans la source

    SQLite 3.31 et versions ultérieures calculent les colonnes générées des deux mêmes façons.

  • generated columns with functions SQLite lacks

    une colonne simple

    Une formule qui ne peut pas être écrite pour SQLite laisse une colonne simple et une ligne dans le rapport.

    Ligne du rapport: generated_not_translated

  • INVISIBLE columns

    colonnes ordinaires

    SQLite n'a pas de colonnes invisibles.

    Ligne du rapport: invisible_column

  • CHECK constraints

    traduites, en ligne dans CREATE TABLE

    SQLite n'accepte les contraintes CHECK que dans CREATE TABLE.

  • CHECK constraints with functions SQLite lacks

    non créée

    Une contrainte CHECK qui ne peut pas être écrite pour SQLite est omise et signalée.

    Ligne du rapport: check_skipped

  • CHECK ... NOT ENFORCED

    non créée

    MySQL garde ces contraintes CHECK sans les appliquer, donc les lignes peuvent les enfreindre.

    Ligne du rapport: check_not_enforced

  • defaults with functions SQLite lacks

    aucune valeur par défaut

    Une valeur par défaut qui ne peut pas être écrite pour SQLite est omise et signalée.

    Ligne du rapport: default_not_translated

  • keys and indexes on a prefix, c(20)

    un index sur substr(c, 1, 20)

    SQLite indexe des expressions, donc le même préfixe est indexé et un préfixe unique reste unique.

    Ligne du rapport: prefix_unique

  • FULLTEXT indexes

    non créée

    SQLite cherche dans le texte avec des tables FTS5 séparées, qui demandent leurs propres requêtes.

    Ligne du rapport: fulltext_not_created

  • SPATIAL indexes

    non créée

    SQLite n'a pas d'index spatial sur une colonne.

    Ligne du rapport: spatial_index_not_created

  • functional indexes SQLite can't write

    non créé

    Un index sur une expression qui ne peut pas être écrite pour SQLite est omis et signalé.

    Ligne du rapport: index_skipped

  • foreign keys

    dans CREATE TABLE, chargées sans vérification, puis listées par PRAGMA foreign_key_check

    SQLite n'accepte les clés étrangères que dans CREATE TABLE et ne les vérifie qu'avec PRAGMA foreign_keys activé. Les lignes se chargent sans vérification, comme depuis MySQL, et le script finit en listant toute ligne sans parent.

  • foreign keys to columns without a unique key

    non créée

    SQLite exige une clé unique sur les colonnes référencées ; InnoDB non.

    Ligne du rapport: foreign_key_skipped

  • table, index and column names

    tels qu'écrits ; renommés s'ils ne diffèrent que par la casse ou si un nom d'index se répète

    Les noms SQLite ignorent la casse, et les noms d'index partagent un seul espace de noms par base de données.

    Ligne du rapport: identifier_renamed

  • GEOMETRY, POINT, POLYGON...

    WKB dans un BLOB

    Le format binaire standard (well-known binary) garde chaque géométrie à l'identique.

    Ligne du rapport: geometry_as_blob

  • INET4, INET6, UUID (MariaDB)

    TEXT

    SQLite n'a pas ces types ; le texte est celui que MariaDB renvoie.

  • BINARY, VARBINARY, BLOB

    BLOB

    Les octets restent des octets.

  • PARTITION BY

    une seule table

    Les lignes sont les mêmes.

    Ligne du rapport: partitions_dropped

  • WITH SYSTEM VERSIONING (MariaDB)

    une table avec les lignes actuelles

    Un dump ne contient que les lignes actuelles.

    Ligne du rapport: system_versioning_dropped

  • MyISAM, MEMORY and other engines

    une table ordinaire

    SQLite a un seul moteur de tables.

    Ligne du rapport: engine_dropped

  • dumps of several databases

    un seul fichier, chaque table préfixée par le nom de sa base

    Un fichier SQLite est une seule base de données ; le nom de la base distingue donc les tables de même nom.

    Ligne du rapport: databases_merged

  • views, triggers, procedures, functions and events

    listés dans le rapport

    Leur code est écrit dans le langage de MySQL ; ils sont donc listés pour que vous les recréiez.

    Ligne du rapport: not_converted_objects

  • dumps without CREATE TABLE

    types déduits des valeurs

    Un dump fait avec --no-create-info ne contient que des lignes, donc les types viennent des valeurs.

    Ligne du rapport: no_schema

  • geometries in a dump without CREATE TABLE

    WKB dans un BLOB

    Le format de géométrie de MySQL est reconnu à partir des valeurs et stocké en WKB standard.

    Ligne du rapport: geometry_as_blob

  • _ci collations

    comparaison exacte

    SQLite compare le texte exactement sauf indication contraire, et son NOCASE ne traite que les lettres ASCII.

    Ligne du rapport: case_insensitive_collation

  • SET NAMES utf8 from utf8mb4 tables

    converti, avec un avertissement

    Le mysqldump de MySQL 5.x écrit par défaut en utf8 sur 3 octets et remplace chaque emoji par un point d'interrogation avant qu'un convertisseur ne voie le fichier.

    Ligne du rapport: dump_lost_four_byte_chars

  • dumps without SET NAMES whose text isn't UTF-8

    lu comme Latin-1 (Windows-1252)

    Le latin1 de MySQL est le Windows-1252, l'encodage habituel de ces dumps.

    Ligne du rapport: charset_guessed

  • sjis, cp932, gbk, big5 dumps

    lu comme UTF-8, avec un avertissement

    Ces encodages ne sont pas encore décodés.

    Ligne du rapport: unsupported_charset

  • UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows

    évaluées

    Certains outils de dump écrivent les valeurs sous forme de ces appels ; ils sont lus comme les valeurs qu'ils produisent, le WKT géographique étant remis avec la longitude en premier.

  • other expressions in rows

    NULL

    Un convertisseur qui n'exécute pas de base de données ne peut pas les évaluer.

    Ligne du rapport: expression_value

  • DEFAULT in VALUES

    la valeur par défaut de la colonne

    Une valeur par défaut littérale est copiée dans la ligne.

    Ligne du rapport: default_keyword_filled

  • DEFAULT in VALUES without a literal default

    NULL

    Il n'y a aucune valeur à copier.

    Ligne du rapport: default_keyword_null

  • REPLACE and INSERT IGNORE

    lignes simples

    Un dump a une ligne par clé, donc les lignes sont les mêmes.

    Ligne du rapport: replace_as_insert

  • types IntoSQL doesn't know

    TEXT

    Le texte contient n'importe quelle valeur ; changez le type après le chargement.

    Ligne du rapport: unknown_type

  • values that don't fit their column

    NULL

    Un dump endommagé ou écrit à la main peut contenir des valeurs que sa colonne n'accepte pas ; elles deviennent NULL pour que le reste se charge.

    Ligne du rapport: invalid_value_null

  • unreadable geometries

    NULL

    Des octets qui ne forment pas une géométrie ne peuvent pas être stockés comme telle.

    Ligne du rapport: bad_geometry

  • CREATE SEQUENCE (MariaDB)

    non créée

    SQLite n'a pas de séquences.

    Ligne du rapport: sequence_not_converted

  • VECTOR(n) (MariaDB 11.7+)

    TEXT avec les flottants en tableau JSON

    SQLite n'a pas de type vector ; un tableau JSON garde chaque flottant.

    Ligne du rapport: type_replaced

Dans MySQLDans SQLiteLigne du rapport
TINYINT(1), BOOLINTEGER avec les valeurs telles quellesSQLite n'a pas de type booléen ; vrai et faux sont les entiers 1 et 0, donc chaque valeur garde son sens.
UNSIGNED integersINTEGER avec un CHECK qui interdit les négatifs ; BIGINT UNSIGNED avec des valeurs au-delà de 2^63-1 devient TEXTLes entiers SQLite font 64 bits et sont signés. Le CHECK écarte les valeurs négatives comme le faisait MySQL ; les valeurs hors de la plage signée sont gardées en texte pour ne perdre aucun chiffre.unsigned_widened
ZEROFILL and display widthssuppriméLe remplissage par des zéros est une façon d'afficher un nombre, pas une partie du nombre. Les nombres sont conservés ; formatez-les à la lecture si le remplissage compte.zerofill_dropped
FLOAT(M,D)REAL, sans l'échelleLes flottants SQLite n'ont pas d'échelle fixe. Les valeurs stockées sont copiées telles quelles.float_scale_dropped
DECIMAL(p,s)DECIMAL(p,s) jusqu'à 15 chiffres ; TEXT au-delàSQLite garde environ 15 chiffres significatifs dans un nombre. Les décimaux plus larges sont gardés en texte pour que chaque chiffre reste exact.decimal_as_text
BIT(1), BIT(n)INTEGER avec la valeur des bits ; BIT(64) en chiffres TEXTUn champ de bits est stocké comme le nombre que forment ses bits. Le bit de poids fort d'un BIT(64) ne tient pas dans un entier signé, donc son nombre est gardé en texte.
zero, partial or impossible dates (0000-00-00, 2024-02-30)NULLLes fonctions de date de SQLite ne lisent que de vraies dates du calendrier. Elles deviennent NULL et le rapport les compte, comme pour toutes les autres bases de données.invalid_date_null
NOT NULL columns with values that become NULLNOT NULL retiréUne colonne dont des valeurs ont dû devenir NULL ne peut pas garder NOT NULL, sinon le chargement s'arrêterait.not_null_relaxed
DEFAULT '0000-00-00'aucune valeur par défautUne valeur par défaut qui n'est pas une vraie date est omise plutôt que remplacée par une date inventée.zero_date_default
TIMEtexte TIME tel que MySQL l'écrit, durées comprisesSQLite garde les heures en texte, donc les durées de plus d'un jour ou négatives sont gardées exactement.
YEARINTEGER avec un CHECK de sa plageSQLite n'a pas de type année ; le CHECK garde les mêmes valeurs que MySQL autorise.
CHAR(n), VARCHAR(n)VARCHAR(n), non appliquéSQLite garde le type déclaré pour les outils mais ne limite pas la longueur ; les valeurs sont celles que MySQL renvoie.
DATETIMEDATETIME en texte ISO 8601SQLite stocke les dates en texte que ses fonctions de date savent lire.
TIMESTAMPTIMESTAMP en texte ISO 8601 en UTC ; le fuseau indiqué par le dump, UTC s'il n'en indique aucunUn TIMESTAMP est un instant, écrit en UTC. Les dumps indiquent le fuseau dans lequel ils l'ont écrit (mysqldump écrit en UTC) ; sinon, les valeurs sont lues en UTC et le rapport le signale.timestamp_zone_assumed
ENUMTEXT avec un CHECK de ses valeursUn texte avec une contrainte CHECK garde les mêmes valeurs.
ENUM holding '' (MySQL's error value)la valeur vide autorisée par le CHECKMySQL stocke une chaîne vide quand une valeur invalide entre dans un ENUM avec un mode SQL permissif. Ces lignes sont conservées et la contrainte CHECK les autorise.enum_invalid_value
ENUM holding values outside its listpas de CHECKLes valeurs absentes de la liste feraient échouer la contrainte CHECK, qui n'est donc pas créée.enum_check_skipped
SETTEXT tel que MySQL l'écrit ('a,b')SQLite n'a pas de tableaux ; le texte est celui que MySQL renvoie.
JSONTEXTLes fonctions JSON de SQLite lisent le JSON depuis du texte. Une colonne déclarée JSON transformerait "123" en nombre, elle est donc en TEXT.
NUL bytes in textconservéLe texte SQLite peut contenir un octet NUL, donc la valeur est copiée telle quelle.
text that isn't valid in its character setles octets invalides deviennent le caractère de remplacementLe texte SQLite est en UTF-8 ; ses fonctions lisent mal les octets qui ne le sont pas.invalid_utf8_replaced
text decoded twice (ñ)copié tel quelLe dump contient exactement ces caractères, ils sont donc copiés ; le rapport les signale.mojibake_suspected
AUTO_INCREMENTINTEGER PRIMARY KEY AUTOINCREMENT, avec le compteur placé après les identifiants copiésSQLite compte une clé primaire entière de type entier. AUTOINCREMENT empêche de réutiliser les identifiants, comme MySQL, et le compteur reprend après le plus élevé ou après l'AUTO_INCREMENT du dump, selon le plus grand.
AUTO_INCREMENT on part of a key or outside oneINTEGER sans compteurSQLite ne compte qu'une colonne qui forme toute la clé primaire ; la colonne garde donc ses valeurs et les nouvelles lignes doivent fournir les leurs.identity_without_counter
ON UPDATE CURRENT_TIMESTAMPun déclencheur AFTER UPDATELe déclencheur met la colonne à l'heure actuelle quand une ligne change et que la mise à jour ne l'a pas définie, comme le fait MySQL.on_update_trigger
generated columnsGENERATED ALWAYS AS, VIRTUAL ou STORED comme dans la sourceSQLite 3.31 et versions ultérieures calculent les colonnes générées des deux mêmes façons.
generated columns with functions SQLite lacksune colonne simpleUne formule qui ne peut pas être écrite pour SQLite laisse une colonne simple et une ligne dans le rapport.generated_not_translated
INVISIBLE columnscolonnes ordinairesSQLite n'a pas de colonnes invisibles.invisible_column
CHECK constraintstraduites, en ligne dans CREATE TABLESQLite n'accepte les contraintes CHECK que dans CREATE TABLE.
CHECK constraints with functions SQLite lacksnon crééeUne contrainte CHECK qui ne peut pas être écrite pour SQLite est omise et signalée.check_skipped
CHECK ... NOT ENFORCEDnon crééeMySQL garde ces contraintes CHECK sans les appliquer, donc les lignes peuvent les enfreindre.check_not_enforced
defaults with functions SQLite lacksaucune valeur par défautUne valeur par défaut qui ne peut pas être écrite pour SQLite est omise et signalée.default_not_translated
keys and indexes on a prefix, c(20)un index sur substr(c, 1, 20)SQLite indexe des expressions, donc le même préfixe est indexé et un préfixe unique reste unique.prefix_unique
FULLTEXT indexesnon crééeSQLite cherche dans le texte avec des tables FTS5 séparées, qui demandent leurs propres requêtes.fulltext_not_created
SPATIAL indexesnon crééeSQLite n'a pas d'index spatial sur une colonne.spatial_index_not_created
functional indexes SQLite can't writenon crééUn index sur une expression qui ne peut pas être écrite pour SQLite est omis et signalé.index_skipped
foreign keysdans CREATE TABLE, chargées sans vérification, puis listées par PRAGMA foreign_key_checkSQLite n'accepte les clés étrangères que dans CREATE TABLE et ne les vérifie qu'avec PRAGMA foreign_keys activé. Les lignes se chargent sans vérification, comme depuis MySQL, et le script finit en listant toute ligne sans parent.
foreign keys to columns without a unique keynon crééeSQLite exige une clé unique sur les colonnes référencées ; InnoDB non.foreign_key_skipped
table, index and column namestels qu'écrits ; renommés s'ils ne diffèrent que par la casse ou si un nom d'index se répèteLes noms SQLite ignorent la casse, et les noms d'index partagent un seul espace de noms par base de données.identifier_renamed
GEOMETRY, POINT, POLYGON...WKB dans un BLOBLe format binaire standard (well-known binary) garde chaque géométrie à l'identique.geometry_as_blob
INET4, INET6, UUID (MariaDB)TEXTSQLite n'a pas ces types ; le texte est celui que MariaDB renvoie.
BINARY, VARBINARY, BLOBBLOBLes octets restent des octets.
PARTITION BYune seule tableLes lignes sont les mêmes.partitions_dropped
WITH SYSTEM VERSIONING (MariaDB)une table avec les lignes actuellesUn dump ne contient que les lignes actuelles.system_versioning_dropped
MyISAM, MEMORY and other enginesune table ordinaireSQLite a un seul moteur de tables.engine_dropped
dumps of several databasesun seul fichier, chaque table préfixée par le nom de sa baseUn fichier SQLite est une seule base de données ; le nom de la base distingue donc les tables de même nom.databases_merged
views, triggers, procedures, functions and eventslistés dans le rapportLeur code est écrit dans le langage de MySQL ; ils sont donc listés pour que vous les recréiez.not_converted_objects
dumps without CREATE TABLEtypes déduits des valeursUn dump fait avec --no-create-info ne contient que des lignes, donc les types viennent des valeurs.no_schema
geometries in a dump without CREATE TABLEWKB dans un BLOBLe format de géométrie de MySQL est reconnu à partir des valeurs et stocké en WKB standard.geometry_as_blob
_ci collationscomparaison exacteSQLite compare le texte exactement sauf indication contraire, et son NOCASE ne traite que les lettres ASCII.case_insensitive_collation
SET NAMES utf8 from utf8mb4 tablesconverti, avec un avertissementLe mysqldump de MySQL 5.x écrit par défaut en utf8 sur 3 octets et remplace chaque emoji par un point d'interrogation avant qu'un convertisseur ne voie le fichier.dump_lost_four_byte_chars
dumps without SET NAMES whose text isn't UTF-8lu comme Latin-1 (Windows-1252)Le latin1 de MySQL est le Windows-1252, l'encodage habituel de ces dumps.charset_guessed
sjis, cp932, gbk, big5 dumpslu comme UTF-8, avec un avertissementCes encodages ne sont pas encore décodés.unsupported_charset
UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rowsévaluéesCertains outils de dump écrivent les valeurs sous forme de ces appels ; ils sont lus comme les valeurs qu'ils produisent, le WKT géographique étant remis avec la longitude en premier.
other expressions in rowsNULLUn convertisseur qui n'exécute pas de base de données ne peut pas les évaluer.expression_value
DEFAULT in VALUESla valeur par défaut de la colonneUne valeur par défaut littérale est copiée dans la ligne.default_keyword_filled
DEFAULT in VALUES without a literal defaultNULLIl n'y a aucune valeur à copier.default_keyword_null
REPLACE and INSERT IGNORElignes simplesUn dump a une ligne par clé, donc les lignes sont les mêmes.replace_as_insert
types IntoSQL doesn't knowTEXTLe texte contient n'importe quelle valeur ; changez le type après le chargement.unknown_type
values that don't fit their columnNULLUn dump endommagé ou écrit à la main peut contenir des valeurs que sa colonne n'accepte pas ; elles deviennent NULL pour que le reste se charge.invalid_value_null
unreadable geometriesNULLDes octets qui ne forment pas une géométrie ne peuvent pas être stockés comme telle.bad_geometry
CREATE SEQUENCE (MariaDB)non crééeSQLite n'a pas de séquences.sequence_not_converted
VECTOR(n) (MariaDB 11.7+)TEXT avec les flottants en tableau JSONSQLite n'a pas de type vector ; un tableau JSON garde chaque flottant.type_replaced

Charger le script dans SQLite

Le script crée les tables, copie les lignes, puis ajoute les clés, les index et les clés étrangères ; il se charge donc vite et s'arrête à la première erreur.

sqlite3 -bail mydb.sqlite < mysql.sqlite.sql

Les clés étrangères sont déclarées dans chaque table et les lignes se chargent sans vérification des clés étrangères. Le script liste ensuite toute ligne qui pointe vers une ligne qui n'existe pas, au lieu d'échouer à mi-chemin.

Pour un gros dump, chargez-le dans un nouveau fichier sur un disque local. Le script charge tout dans une seule transaction sans synchronisation, il va donc à la vitesse du disque, et un chargement interrompu ne laisse aucune table partielle.

La ligne de commande charge le fichier directement dans une base SQLite, sans écrire de script. C'est gratuit.

Faire le dump MySQL pour un meilleur résultat

Le convertisseur lit ce que contient le dump. Ces options y gardent davantage de vos données :

  • --default-character-set=utf8mb4 garde les emoji et autres caractères sur 4 octets, qu'un dump utf8 perd avant que le convertisseur ne le voie.
  • --hex-blob écrit les colonnes binaires en hexadécimal, ce qui résiste aux copies entre systèmes.
  • --routines --triggers --events ajoutent ces objets au dump, pour que le rapport puisse les lister.

Ce qui n'est pas converti

Les vues, déclencheurs, procédures stockées, fonctions et événements sont écrits dans le langage propre à chaque base de données. Ils sont listés par nom dans le rapport, jamais supprimés en silence, pour que vous puissiez les réécrire pour SQLite.

Questions sur MySQL vers SQLite

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.

Lit-il les dumps MariaDB ?

Oui. Les dumps de mariadb-dump et de MariaDB 10.3 à 12 se convertissent de la même façon, y compris les colonnes INET6, INET4 et UUID de MariaDB.

Que deviennent les dates 0000-00-00 ?

Elles deviennent NULL : SQLite stockerait le texte, mais rien ne lit 0000-00-00 comme une date. Le rapport indique combien il y en avait dans chaque colonne.

Les valeurs AUTO_INCREMENT sont-elles conservées ?

Oui. Une colonne AUTO_INCREMENT qui forme toute la clé primaire de la table devient INTEGER PRIMARY KEY AUTOINCREMENT, chaque ligne garde son identifiant, et le prochain identifiant reprend après le plus élevé. Toute autre colonne AUTO_INCREMENT garde ses valeurs sans compteur, et le rapport le signale.

TINYINT(1) devient-il boolean ?

Non. SQLite n'a pas de type booléen, donc TINYINT(1) est un INTEGER et chaque valeur reste telle quelle.

Et les procédures stockées et les déclencheurs ?

Ils sont listés par nom dans le rapport et ne sont pas convertis, car chaque base de données les écrit dans son propre langage. ON UPDATE CURRENT_TIMESTAMP est l'exception : il devient un déclencheur SQLite.

Sur quelles versions de SQLite le script se charge-t-il ?

SQLite 3.31 et versions ultérieures. Chaque dump de test se charge sur 3.31 et 3.54, et s'arrête à la première erreur en cas de problème.