Naar de inhoud
IntoSQL-startpagina

Een SQLite-database verhuizen naar een oudere of nieuwere SQLite

Sleep een SQLite-databasebestand (.db, .sqlite, .sqlite3) of de SQL die .dump van sqlite3 schrijft hierheen en download een script dat laadt op SQLite 3.31 en later. Elke kolom behoudt zijn gedeclareerde type en collatie, STRICT wordt weggelaten zodat oudere versies de tabellen accepteren, en elke wijziging staat in het rapport.

Je bestand
sqlshop_2024_sqlite.sqlVoorbeeldbestand, 3,4 kB
Je database

18 rijen geconverteerd, geen correcties, geen afgewezen

Tonen

Tabellen in shop_2024_sqlite.sqlSQLite-dump · geschreven door sqlite3 · utf-8

  • customers8 rijen
    7 kolommen
    idINTEGER not null
    nameTEXT not null
    emailTEXT not null
    countryTEXT not null
    is_activeINTEGER not null
    signed_upDATE
    created_atDATETIME not null
  • orders10 rijen
    9 kolommen
    idINTEGER not null
    customer_idINTEGER not null
    statusTEXT not null
    totalDECIMAL(10,2) not null
    itemsINTEGER not null
    ordered_atDATETIME not null
    shipped_atDATETIME
    noteTEXT
    receiptBLOB

Niet geconverteerd

  • Weergave order_totals
  • Trigger orders_shipped

Elke database schrijft deze in een eigen taal. Herschrijf ze voor SQLite.

-- Written by IntoSQL from a SQLite dump. Load it with: sqlite3 -bail <database> < <file>
PRAGMA foreign_keys = OFF;
PRAGMA synchronous = OFF;
BEGIN;

CREATE TABLE customers (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    email TEXT COLLATE NOCASE NOT NULL,
    country TEXT DEFAULT 'US' NOT NULL,
    is_active INTEGER DEFAULT 1 NOT NULL,
    signed_up DATE,
    created_at DATETIME DEFAULT (datetime('now', 'localtime')) NOT NULL,
    CONSTRAINT customers_is_active_check CHECK (is_active IN (0, 1)),
    CONSTRAINT customers_check1 CHECK (length(country) = 2)
);

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 TEXT,
    receipt BLOB,
    CONSTRAINT orders_check1 CHECK (status IN ('pending', 'paid', 'shipped', 'cancelled')),
    CONSTRAINT orders_fkey FOREIGN KEY (customer_id) REFERENCES customers (id) ON DELETE CASCADE
);

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');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(2,'Zoë Müller','zoe@example.de','DE',1,'2023-02-03','2023-02-03 08:11:42');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(3,'José Peña','jose@example.es','ES',0,'2023-03-21','2023-03-21 19:05:17');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(4,'李雷','lilei@example.cn','CN',1,'2023-05-09','2023-05-09 02:40:00');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(5,'Noah O''Brien','noah@example.ie','IE',1,NULL,'2023-06-30 14:00:00');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(6,'Amélie Laurent','amelie@example.fr','FR',1,'2024-01-02','2024-01-02 09:30:00');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(7,'Ravi Patel','ravi@example.in','IN',0,'2024-02-29','2024-02-29 23:59:59');
INSERT INTO customers (id, name, email, country, is_active, signed_up, created_at) VALUES
(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, receipt) VALUES
(1,1,'shipped',129.9,3,'2024-03-01 10:00:00','2024-03-02 16:30:00',NULL,NULL);
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, receipt) VALUES
(2,2,'paid',54,1,'2024-03-02 11:15:00',NULL,'Gift wrap 🎁',NULL);
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, receipt) VALUES
(3,1,'cancelled',12.5,1,'2024-03-03 09:45:00',NULL,'Customer changed their mind',NULL);
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, receipt) VALUES
(4,4,'shipped',980,12,'2024-03-05 02:10:00','2024-03-07 08:00:00','请小心轻放',X'25504446');
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, receipt) VALUES
(5,5,'pending',45.75,2,'2024-03-08 17:20:00',NULL,'Leave at the door;
ring twice',NULL);
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, receipt) VALUES
(6,6,'shipped',310.4,5,'2024-03-10 13:00:00','2024-03-11 09:00:00','Fragile: "glass"',NULL);
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, receipt) VALUES
(7,8,'paid',76.2,2,'2024-03-11 18:45:00',NULL,NULL,NULL);
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, receipt) VALUES
(8,2,'paid',19.99,1,'2024-03-12 08:00:00',NULL,'Paid at the counter',NULL);
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, receipt) VALUES
(9,3,'shipped',64,2,'2024-03-14 15:30:00',NULL,'Shipping date never recorded',NULL);
INSERT INTO orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, receipt) VALUES
(10,7,'paid',1499,1,'2024-03-15 21:05:00',NULL,'C:\Users\ravi\invoice.pdf',NULL);

-- Indexes, triggers and counters, after the rows so each index builds once.
CREATE UNIQUE INDEX customers_email ON customers (email);
CREATE INDEX orders_idx_orders_customer ON orders (customer_id);
CREATE INDEX orders_idx_orders_status_date ON orders (status, ordered_at);
UPDATE sqlite_sequence SET seq = max(seq, 8) WHERE name = 'customers';
INSERT INTO sqlite_sequence (name, seq) SELECT 'customers', 8 WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = 'customers');
UPDATE sqlite_sequence SET seq = max(seq, 10) WHERE name = 'orders';
INSERT INTO sqlite_sequence (name, seq) SELECT 'orders', 10 WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = 'orders');
COMMIT;

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

Correcties

Er hoefde niets gecorrigeerd te worden.

Na te kijken

  • 2 weergaven, triggers, routines of gebeurtenissen zijn niet geconverteerd; het rapport noemt ze allemaal. Maak ze met de hand opnieuw aan in SQLite.

Je bestand wordt op deze computer omgezet en nooit geüpload.

Andere voorbeelden:

Wat er verandert tussen het bestand en het script

Elke rij is een regel die de converter toepast, met de rapportregel die hij schrijft als de regel iets in je data verandert.

  • declared types (any text: VARCHAR(255), DATETIME, BOOLEAN, JSON or none)

    het type waarin elke waarde in de kolom past

    Dezelfde gedeclareerde typen, dus de waarden laden zoals ze waren opgeslagen.

  • BOOLEAN, BOOL

    INTEGER 0 of 1 met een CHECK

    Als elke waarde 0 of 1 is; een kolom die ook andere waarden bevat, behoudt ze als getallen of tekst.

  • TEXT, VARCHAR(n), CHAR(n), CLOB

    het gedeclareerde type, ongewijzigd

    SQLite dwingt nooit een lengte af; een gedeclareerde lengte geldt alleen als elke waarde erin past.

  • DECIMAL(p,s), NUMERIC

    het exacte type als elke waarde erin past, anders een double

    SQLite slaat deze op als gehele getallen of doubles; een gedeclareerde precisie geldt alleen als de waarden erin passen.

  • BLOB, and columns holding bytes

    BLOB

    Bytes blijven bytes; tekst en getallen in dezelfde kolom blijven behouden als hun bytes.

  • DATE, DATETIME, TIMESTAMP holding ISO 8601 text

    DATE, DATETIME als ISO 8601-tekst

    Als elke waarde een datum of een datum met tijd is; epoch-getallen en andere tekst behouden hun waarden ongewijzigd.

  • JSON holding JSON text

    TEXT

    Als elke waarde een JSON-object of -array is.

  • Infinity in REAL columns

    9e999, het eigen oneindig van SQLite

    SQLite schrijft oneindig als een overlopende literal, die weer als oneindig laadt.

  • INTEGER PRIMARY KEY, AUTOINCREMENT

    INTEGER PRIMARY KEY, AUTOINCREMENT behouden

    Alleen een kolom die precies als INTEGER PRIMARY KEY is gedeclareerd, is de rowid; elke rij behoudt zijn id, en de teller begint na het hoogste id dat ooit is uitgegeven.

  • COLLATE NOCASE

    COLLATE NOCASE

    Dezelfde collatie.

  • generated columns

    gegenereerde kolommen, STORED of VIRTUAL zoals in de bron

    SQLite berekent ze op dezelfde manier.

  • generated columns with functions IntoSQL doesn't write, and the || operator

    een gewone kolom

    Een formule die niet kan worden geschreven, levert een gewone kolom en een regel in het rapport op; de dump bevat geen waarden voor gegenereerde kolommen.

    Rapportregel: generated_not_translated

  • defaults with functions IntoSQL doesn't write (strftime, randomblob)

    geen standaardwaarde

    Een standaardwaarde die niet kan worden geschreven, wordt weggelaten en gemeld; CURRENT_TIMESTAMP en datetime('now') worden wel geschreven.

    Rapportregel: default_not_translated

  • CHECK constraints

    vertaald

    Dezelfde checks, getest terwijl elke rij laadt.

  • CHECK constraints with functions IntoSQL doesn't write

    niet aangemaakt

    Een check die niet kan worden geschreven, wordt weggelaten en gemeld.

    Rapportregel: check_skipped

  • partial and expression indexes

    niet aangemaakt

    IntoSQL schrijft indexen op hele kolommen; maak de andere na het laden opnieuw aan.

    Rapportregel: index_skipped

  • foreign keys (unenforced unless PRAGMA foreign_keys=ON)

    dezelfde refererende sleutels, opgesomd door PRAGMA foreign_key_check

    SQLite controleert refererende sleutels alleen als dat gevraagd wordt, dus rijen zonder ouder komen vaak voor: ze laden, en de sleutel blijft ongecontroleerd met een waarschuwing, in plaats van het laden te stoppen.

  • foreign keys to tables the dump doesn't create

    niet aangemaakt

    Een sleutel kan niet verwijzen naar een tabel die er niet is.

    Rapportregel: foreign_key_skipped

  • primary keys holding NULL, and NOT NULL columns with values that become NULL

    NOT NULL weggelaten

    SQLite staat NULL toe in een primaire sleutel die niet de rowid is; de kolom kan in het doel niet NOT NULL zijn, anders zou het laden stoppen.

    Rapportregel: not_null_relaxed

  • views, triggers and virtual tables (FTS, R*Tree)

    vermeld in het rapport

    Hun code is geschreven in de eigen taal van SQLite, en virtuele tabellen hebben de modules van SQLite nodig; ze worden vermeld zodat je ze opnieuw kunt maken. Hun interne tabellen worden niet gekopieerd.

    Rapportregel: not_converted_objects

  • dumps without CREATE TABLE (--data-only)

    typen afgeleid uit de waarden

    Een dump met alleen data bevat alleen rijen, dus de typen komen uit de waarden en de kolommen worden genummerd.

    Rapportregel: no_schema

  • expressions in INSERT values other than the text functions dumps write

    NULL

    unistr(), replace(), char() en || worden geëvalueerd zoals de shell ze schrijft; andere expressies kunnen zonder database niet worden geëvalueerd.

    Rapportregel: expression_value

  • NUL characters in text

    behouden

    De sqlite3-shell en Python kappen tekst af bij een NUL-teken als ze hem dumpen, dus alleen wat ervoor staat, zit in de dump.

  • text that isn't valid UTF-8

    de foute bytes als het vervangingsteken

    Dumps schrijven zulke tekst als ruwe bytes; het script is UTF-8.

    Rapportregel: invalid_utf8_replaced

  • text decoded twice (ñ)

    ongewijzigd gekopieerd

    De dump bevat precies deze tekens, dus ze worden gekopieerd; het rapport wijst ze aan.

    Rapportregel: mojibake_suspected

In het bestandIn het scriptRapportregel
declared types (any text: VARCHAR(255), DATETIME, BOOLEAN, JSON or none)het type waarin elke waarde in de kolom pastDezelfde gedeclareerde typen, dus de waarden laden zoals ze waren opgeslagen.
BOOLEAN, BOOLINTEGER 0 of 1 met een CHECKAls elke waarde 0 of 1 is; een kolom die ook andere waarden bevat, behoudt ze als getallen of tekst.
TEXT, VARCHAR(n), CHAR(n), CLOBhet gedeclareerde type, ongewijzigdSQLite dwingt nooit een lengte af; een gedeclareerde lengte geldt alleen als elke waarde erin past.
DECIMAL(p,s), NUMERIChet exacte type als elke waarde erin past, anders een doubleSQLite slaat deze op als gehele getallen of doubles; een gedeclareerde precisie geldt alleen als de waarden erin passen.
BLOB, and columns holding bytesBLOBBytes blijven bytes; tekst en getallen in dezelfde kolom blijven behouden als hun bytes.
DATE, DATETIME, TIMESTAMP holding ISO 8601 textDATE, DATETIME als ISO 8601-tekstAls elke waarde een datum of een datum met tijd is; epoch-getallen en andere tekst behouden hun waarden ongewijzigd.
JSON holding JSON textTEXTAls elke waarde een JSON-object of -array is.
Infinity in REAL columns9e999, het eigen oneindig van SQLiteSQLite schrijft oneindig als een overlopende literal, die weer als oneindig laadt.
INTEGER PRIMARY KEY, AUTOINCREMENTINTEGER PRIMARY KEY, AUTOINCREMENT behoudenAlleen een kolom die precies als INTEGER PRIMARY KEY is gedeclareerd, is de rowid; elke rij behoudt zijn id, en de teller begint na het hoogste id dat ooit is uitgegeven.
COLLATE NOCASECOLLATE NOCASEDezelfde collatie.
generated columnsgegenereerde kolommen, STORED of VIRTUAL zoals in de bronSQLite berekent ze op dezelfde manier.
generated columns with functions IntoSQL doesn't write, and the || operatoreen gewone kolomEen formule die niet kan worden geschreven, levert een gewone kolom en een regel in het rapport op; de dump bevat geen waarden voor gegenereerde kolommen.generated_not_translated
defaults with functions IntoSQL doesn't write (strftime, randomblob)geen standaardwaardeEen standaardwaarde die niet kan worden geschreven, wordt weggelaten en gemeld; CURRENT_TIMESTAMP en datetime('now') worden wel geschreven.default_not_translated
CHECK constraintsvertaaldDezelfde checks, getest terwijl elke rij laadt.
CHECK constraints with functions IntoSQL doesn't writeniet aangemaaktEen check die niet kan worden geschreven, wordt weggelaten en gemeld.check_skipped
partial and expression indexesniet aangemaaktIntoSQL schrijft indexen op hele kolommen; maak de andere na het laden opnieuw aan.index_skipped
foreign keys (unenforced unless PRAGMA foreign_keys=ON)dezelfde refererende sleutels, opgesomd door PRAGMA foreign_key_checkSQLite controleert refererende sleutels alleen als dat gevraagd wordt, dus rijen zonder ouder komen vaak voor: ze laden, en de sleutel blijft ongecontroleerd met een waarschuwing, in plaats van het laden te stoppen.
foreign keys to tables the dump doesn't createniet aangemaaktEen sleutel kan niet verwijzen naar een tabel die er niet is.foreign_key_skipped
primary keys holding NULL, and NOT NULL columns with values that become NULLNOT NULL weggelatenSQLite staat NULL toe in een primaire sleutel die niet de rowid is; de kolom kan in het doel niet NOT NULL zijn, anders zou het laden stoppen.not_null_relaxed
views, triggers and virtual tables (FTS, R*Tree)vermeld in het rapportHun code is geschreven in de eigen taal van SQLite, en virtuele tabellen hebben de modules van SQLite nodig; ze worden vermeld zodat je ze opnieuw kunt maken. Hun interne tabellen worden niet gekopieerd.not_converted_objects
dumps without CREATE TABLE (--data-only)typen afgeleid uit de waardenEen dump met alleen data bevat alleen rijen, dus de typen komen uit de waarden en de kolommen worden genummerd.no_schema
expressions in INSERT values other than the text functions dumps writeNULLunistr(), replace(), char() en || worden geëvalueerd zoals de shell ze schrijft; andere expressies kunnen zonder database niet worden geëvalueerd.expression_value
NUL characters in textbehoudenDe sqlite3-shell en Python kappen tekst af bij een NUL-teken als ze hem dumpen, dus alleen wat ervoor staat, zit in de dump.
text that isn't valid UTF-8de foute bytes als het vervangingstekenDumps schrijven zulke tekst als ruwe bytes; het script is UTF-8.invalid_utf8_replaced
text decoded twice (ñ)ongewijzigd gekopieerdDe dump bevat precies deze tekens, dus ze worden gekopieerd; het rapport wijst ze aan.mojibake_suspected

Het script in SQLite laden

Het script maakt de tabellen aan, kopieert de rijen en voegt daarna sleutels, indexen en refererende sleutels toe, zodat het snel laadt en bij de eerste fout stopt.

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

Refererende sleutels worden in elke tabel gedeclareerd en de rijen laden met de controle op refererende sleutels uit. Daarna somt het script elke rij op die naar een niet-bestaande rij verwijst, in plaats van halverwege te mislukken.

Laad een grote dump in een nieuw bestand op een lokale schijf. Het script laadt alles in één transactie met synchronisatie uit, dus het draait op schijfsnelheid, en een laadactie die halverwege stopt, laat geen halve tabellen achter.

De opdrachtregel laadt het bestand rechtstreeks in een SQLite-database, zonder een script te schrijven. Dat is gratis.

Een dump van SQLite maken voor het beste resultaat

De converter leest wat de dump bevat. Met deze opties blijft er meer van je data in staan:

  • Het databasebestand zelf wordt ongewijzigd geconverteerd, pagina voor pagina gelezen in je browser. Sluit eerst de app die erin schrijft, zodat er geen wijziging achterblijft in het -wal-bestand.
  • sqlite3 app.db .dump > app.sql schrijft dezelfde database als SQL, die ook wordt geconverteerd, als .sql of .sql.gz.
  • DB Browser for SQLite schrijft die SQL met File, Export, Database to SQL file, en iterdump() in Python ook.

Wat niet wordt geconverteerd

Weergaven, triggers, procedures, functies en andere objecten in de eigen taal van SQLite staan op naam in het rapport en worden nooit stilletjes weggelaten, zodat je elk ervan kunt controleren tegen de SQLite-versie waarin je laadt voordat je het opnieuw aanmaakt.

Vragen over SQLite verhuizen tussen versies

Staat je vraag er niet bij? Schrijf ons via de contactpagina en een mens antwoordt. Contactpagina

Wordt mijn dump geüpload?

Nee. De converter draait in je browser en leest de dump in delen van je schijf, dus hij verlaat je computer nooit. De desktopapp en de opdrachtregel converteren ook op je computer.

Hoe groot mag de dump zijn?

De converter houdt nooit de hele dump in het geheugen: hij leest het bestand twee keer, in bereiken, en schrijft het script gaandeweg. Dumps van meerdere gigabytes worden geconverteerd in de browser, in de desktopapp en met de opdrachtregel.

Kan ik het .db-bestand zelf converteren?

Ja. Zet het .db-, .sqlite- of .sqlite3-bestand neer: het wordt in je browser gelezen en nooit geüpload. Tekst met NUL-tekens en elk cijfer van een double komen aan zoals ze zijn opgeslagen, wat een .dump kan afkappen.

Van welke SQLite-versies kan de dump komen?

Databasebestanden vanaf SQLite 3.0, in UTF-8 of UTF-16, en dumps van .dump in de sqlite3-shell of van iterdump() in Python. Elk testbestand en elke testdump komt van sqlite3 3.31 tot en met 3.54, STRICT- en WITHOUT ROWID-tabellen inbegrepen, en wordt cel voor cel met zijn bron vergeleken.

Hoe worden kolomtypen bepaald als SQLite ze niet afdwingt?

Elke kolom behoudt zijn gedeclareerde type, net als COLLATE NOCASE en RTRIM. STRICT wordt weggelaten, zodat het script laadt op elke versie vanaf 3.31.

Blijven INTEGER PRIMARY KEY en AUTOINCREMENT behouden?

Ja. INTEGER PRIMARY KEY en AUTOINCREMENT blijven zoals ze zijn, en sqlite_sequence gaat verder waar de dump ophield.

En weergaven en triggers?

Ze staan op naam in het rapport en worden niet geconverteerd, zodat je ze opnieuw kunt maken zodra de tabellen er zijn.

Op welke SQLite-versies laadt het script?

SQLite 3.31 en later. Elk testbestand en elke testdump laadt op 3.31 en 3.54 en stopt bij de eerste fout als er iets misgaat.