Porta un database SQLite su un SQLite più vecchio o più recente
Trascina un file di database SQLite (.db, .sqlite, .sqlite3) o l'SQL che scrive .dump di sqlite3, e scarica uno script che si carica su SQLite 3.31 e successivi. Ogni colonna conserva il tipo dichiarato e la collation, STRICT viene omesso perché le versioni più vecchie accettino le tabelle, e ogni modifica è elencata nel report.
18 righe convertite, nessuna correzione, nessuna rifiutata
Tabelle in shop_2024_sqlite.sqlDump SQLite · scritto da sqlite3 · utf-8
customers8 righe
7 colonne id INTEGER not null name TEXT not null email TEXT not null country TEXT not null is_active INTEGER not null signed_up DATE created_at DATETIME not null orders10 righe
9 colonne id INTEGER not null customer_id INTEGER not null status TEXT not null total DECIMAL(10,2) not null items INTEGER not null ordered_at DATETIME not null shipped_at DATETIME note TEXT receipt BLOB
Non convertiti
- Vista order_totals
- Trigger orders_shipped
Ogni database li scrive nel proprio linguaggio. Riscrivili per 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;
Correzioni
Non c'era niente da correggere.
Da controllare
- 2 viste, trigger, routine o eventi non sono convertiti; il report li elenca uno per uno. Ricreali a mano in SQLite.
Il tuo file viene convertito su questo computer e non viene mai caricato.
Altri esempi:
Cosa cambia tra il file e lo script
Ogni riga è una regola che il convertitore applica, con la riga del report che scrive quando la regola cambia qualcosa nei tuoi dati.
declared types (any text: VARCHAR(255), DATETIME, BOOLEAN, JSON or none)
il tipo in cui stanno tutti i valori della colonna
Gli stessi tipi dichiarati, quindi i valori si caricano come erano stati salvati.
BOOLEAN, BOOL
INTEGER 0 o 1 con un CHECK
Quando ogni valore è 0 o 1; una colonna che contiene anche altri valori li mantiene come numeri o testo.
TEXT, VARCHAR(n), CHAR(n), CLOB
il tipo dichiarato, mantenuto così com'è
SQLite non applica mai una lunghezza; una lunghezza dichiarata vale solo quando ogni valore ci sta.
DECIMAL(p,s), NUMERIC
il tipo esatto quando ogni valore ci sta, altrimenti un double
SQLite li salva come interi o double; una precisione dichiarata vale solo quando i valori ci stanno.
BLOB, and columns holding bytes
BLOB
I byte restano byte; testo e numeri nella stessa colonna vengono mantenuti come i loro byte.
DATE, DATETIME, TIMESTAMP holding ISO 8601 text
DATE, DATETIME come testo ISO 8601
Quando ogni valore è una data o una data con ora; i numeri epoch e l'altro testo mantengono i loro valori così come sono.
JSON holding JSON text
TEXT
Quando ogni valore è un oggetto o un array JSON.
Infinity in REAL columns
9e999, l'infinito di SQLite
SQLite scrive l'infinito come un letterale che va in overflow, che ricaricato torna infinito.
INTEGER PRIMARY KEY, AUTOINCREMENT
INTEGER PRIMARY KEY, AUTOINCREMENT mantenuto
Solo una colonna dichiarata esattamente INTEGER PRIMARY KEY è il rowid; ogni riga mantiene il suo id, e il contatore parte dopo l'id più alto mai assegnato.
COLLATE NOCASE
COLLATE NOCASE
La stessa collation.
generated columns
colonne generate, STORED o VIRTUAL come nella sorgente
SQLite le calcola allo stesso modo.
generated columns with functions IntoSQL doesn't write, and the || operator
una colonna semplice
Una formula che non si può scrivere lascia una colonna semplice e una riga nel report; il dump non ha valori per le colonne generate.
Riga del report: generated_not_translated
defaults with functions IntoSQL doesn't write (strftime, randomblob)
nessun valore predefinito
Un valore predefinito che non si può scrivere viene omesso e segnalato; CURRENT_TIMESTAMP e datetime('now') vengono scritti.
Riga del report: default_not_translated
CHECK constraints
tradotti
Gli stessi CHECK, verificati mentre ogni riga si carica.
CHECK constraints with functions IntoSQL doesn't write
non creato
Un vincolo CHECK che non si può scrivere viene omesso e segnalato.
Riga del report: check_skipped
partial and expression indexes
non creato
IntoSQL scrive indici su colonne intere; ricrea gli altri dopo il caricamento.
Riga del report: index_skipped
foreign keys (unenforced unless PRAGMA foreign_keys=ON)
le stesse chiavi esterne, elencate da PRAGMA foreign_key_check
SQLite verifica le chiavi esterne solo quando glielo si chiede, quindi le righe senza padre sono comuni: si caricano, e la chiave resta non controllata con un avviso invece di fermare il caricamento.
foreign keys to tables the dump doesn't create
non creato
Una chiave non può riferirsi a una tabella che non c'è.
Riga del report: foreign_key_skipped
primary keys holding NULL, and NOT NULL columns with values that become NULL
NOT NULL rimosso
SQLite permette a una chiave primaria diversa dal rowid di contenere NULL; la colonna non può essere NOT NULL nella destinazione, altrimenti il caricamento si fermerebbe.
Riga del report: not_null_relaxed
views, triggers and virtual tables (FTS, R*Tree)
elencati nel report
Il loro codice è scritto nel linguaggio di SQLite, e le tabelle virtuali richiedono i moduli di SQLite; sono elencati perché tu li ricrei. Le loro tabelle interne non vengono copiate.
Riga del report: not_converted_objects
dumps without CREATE TABLE (--data-only)
tipi ricavati dai valori
Un dump di soli dati contiene solo righe, quindi i tipi vengono ricavati dai valori e le colonne sono numerate.
Riga del report: no_schema
expressions in INSERT values other than the text functions dumps write
NULL
unistr(), replace(), char() e || vengono valutati come li scrive la shell; le altre espressioni non si possono valutare senza un database.
Riga del report: expression_value
NUL characters in text
mantenuto
La shell sqlite3 e Python tagliano il testo a un carattere NUL quando lo esportano, quindi nel dump c'è solo ciò che lo precede.
text that isn't valid UTF-8
i byte errati come carattere di sostituzione
I dump scrivono quel testo come byte grezzi; lo script è UTF-8.
Riga del report: invalid_utf8_replaced
text decoded twice (ñ)
copiato così com'è
Il dump contiene esattamente questi caratteri, quindi vengono copiati; il report li segnala.
Riga del report: mojibake_suspected
| Nel file | Nello script | Riga del report |
|---|---|---|
| declared types (any text: VARCHAR(255), DATETIME, BOOLEAN, JSON or none) | il tipo in cui stanno tutti i valori della colonnaGli stessi tipi dichiarati, quindi i valori si caricano come erano stati salvati. | |
| BOOLEAN, BOOL | INTEGER 0 o 1 con un CHECKQuando ogni valore è 0 o 1; una colonna che contiene anche altri valori li mantiene come numeri o testo. | |
| TEXT, VARCHAR(n), CHAR(n), CLOB | il tipo dichiarato, mantenuto così com'èSQLite non applica mai una lunghezza; una lunghezza dichiarata vale solo quando ogni valore ci sta. | |
| DECIMAL(p,s), NUMERIC | il tipo esatto quando ogni valore ci sta, altrimenti un doubleSQLite li salva come interi o double; una precisione dichiarata vale solo quando i valori ci stanno. | |
| BLOB, and columns holding bytes | BLOBI byte restano byte; testo e numeri nella stessa colonna vengono mantenuti come i loro byte. | |
| DATE, DATETIME, TIMESTAMP holding ISO 8601 text | DATE, DATETIME come testo ISO 8601Quando ogni valore è una data o una data con ora; i numeri epoch e l'altro testo mantengono i loro valori così come sono. | |
| JSON holding JSON text | TEXTQuando ogni valore è un oggetto o un array JSON. | |
| Infinity in REAL columns | 9e999, l'infinito di SQLiteSQLite scrive l'infinito come un letterale che va in overflow, che ricaricato torna infinito. | |
| INTEGER PRIMARY KEY, AUTOINCREMENT | INTEGER PRIMARY KEY, AUTOINCREMENT mantenutoSolo una colonna dichiarata esattamente INTEGER PRIMARY KEY è il rowid; ogni riga mantiene il suo id, e il contatore parte dopo l'id più alto mai assegnato. | |
| COLLATE NOCASE | COLLATE NOCASELa stessa collation. | |
| generated columns | colonne generate, STORED o VIRTUAL come nella sorgenteSQLite le calcola allo stesso modo. | |
| generated columns with functions IntoSQL doesn't write, and the || operator | una colonna sempliceUna formula che non si può scrivere lascia una colonna semplice e una riga nel report; il dump non ha valori per le colonne generate. | generated_not_translated |
| defaults with functions IntoSQL doesn't write (strftime, randomblob) | nessun valore predefinitoUn valore predefinito che non si può scrivere viene omesso e segnalato; CURRENT_TIMESTAMP e datetime('now') vengono scritti. | default_not_translated |
| CHECK constraints | tradottiGli stessi CHECK, verificati mentre ogni riga si carica. | |
| CHECK constraints with functions IntoSQL doesn't write | non creatoUn vincolo CHECK che non si può scrivere viene omesso e segnalato. | check_skipped |
| partial and expression indexes | non creatoIntoSQL scrive indici su colonne intere; ricrea gli altri dopo il caricamento. | index_skipped |
| foreign keys (unenforced unless PRAGMA foreign_keys=ON) | le stesse chiavi esterne, elencate da PRAGMA foreign_key_checkSQLite verifica le chiavi esterne solo quando glielo si chiede, quindi le righe senza padre sono comuni: si caricano, e la chiave resta non controllata con un avviso invece di fermare il caricamento. | |
| foreign keys to tables the dump doesn't create | non creatoUna chiave non può riferirsi a una tabella che non c'è. | foreign_key_skipped |
| primary keys holding NULL, and NOT NULL columns with values that become NULL | NOT NULL rimossoSQLite permette a una chiave primaria diversa dal rowid di contenere NULL; la colonna non può essere NOT NULL nella destinazione, altrimenti il caricamento si fermerebbe. | not_null_relaxed |
| views, triggers and virtual tables (FTS, R*Tree) | elencati nel reportIl loro codice è scritto nel linguaggio di SQLite, e le tabelle virtuali richiedono i moduli di SQLite; sono elencati perché tu li ricrei. Le loro tabelle interne non vengono copiate. | not_converted_objects |
| dumps without CREATE TABLE (--data-only) | tipi ricavati dai valoriUn dump di soli dati contiene solo righe, quindi i tipi vengono ricavati dai valori e le colonne sono numerate. | no_schema |
| expressions in INSERT values other than the text functions dumps write | NULLunistr(), replace(), char() e || vengono valutati come li scrive la shell; le altre espressioni non si possono valutare senza un database. | expression_value |
| NUL characters in text | mantenutoLa shell sqlite3 e Python tagliano il testo a un carattere NUL quando lo esportano, quindi nel dump c'è solo ciò che lo precede. | |
| text that isn't valid UTF-8 | i byte errati come carattere di sostituzioneI dump scrivono quel testo come byte grezzi; lo script è UTF-8. | invalid_utf8_replaced |
| text decoded twice (ñ) | copiato così com'èIl dump contiene esattamente questi caratteri, quindi vengono copiati; il report li segnala. | mojibake_suspected |
Carica lo script in SQLite
Lo script crea le tabelle, copia le righe, poi aggiunge chiavi, indici e chiavi esterne, così si carica in fretta e si ferma al primo errore.
sqlite3 -bail mydb.sqlite < sqlite.sqlite.sqlLe chiavi esterne sono dichiarate in ogni tabella e le righe si caricano con i controlli delle chiavi esterne disattivati. Lo script poi elenca ogni riga che punta a una riga che non esiste, invece di fallire a metà.
Per un dump grande, carica in un file nuovo su un disco locale. Lo script carica tutto in un'unica transazione con la sincronizzazione disattivata, così va alla velocità del disco, e un caricamento che si ferma a metà non lascia tabelle parziali.
La riga di comando carica il file direttamente in un database SQLite, senza scrivere uno script. È gratis.
Fai il dump di SQLite per il miglior risultato
Il convertitore legge ciò che il dump contiene. Con queste opzioni il dump conserva più dei tuoi dati:
- Il file del database si converte così com'è, letto pagina per pagina nel browser. Chiudi prima l'app che ci scrive, così nessuna modifica resta indietro nel suo file -wal.
- sqlite3 app.db .dump > app.sql scrive lo stesso database come SQL, che si converte anch'esso, come .sql o .sql.gz.
- DB Browser for SQLite scrive quel SQL con File, Export, Database to SQL file, e così fa iterdump() di Python.
Cosa non viene convertito
Viste, trigger, procedure, funzioni e altri oggetti scritti nel linguaggio di SQLite sono elencati per nome nel report, mai eliminati in silenzio, così puoi verificare ognuno con la versione di SQLite in cui carichi prima di ricrearlo.
Domande sul passaggio di SQLite tra versioni
Non trovi la risposta? Scrivici dalla pagina dei contatti e ti risponde una persona. Pagina dei contatti
Il mio dump viene caricato?
No. Il convertitore funziona nel tuo browser e legge il dump dal tuo disco a pezzi, quindi non lascia mai il tuo computer. Anche l'app desktop e la riga di comando convertono sul tuo computer.
Quanto può essere grande il dump?
Il convertitore non tiene mai l'intero dump in memoria: legge il file due volte, per intervalli, e scrive lo script man mano. I dump di più gigabyte si convertono nel browser, nell'app desktop e con la riga di comando.
Posso convertire direttamente il file .db?
Sì. Trascina il file .db, .sqlite o .sqlite3: viene letto nel browser e mai caricato. Il testo con caratteri NUL e ogni cifra di un double arrivano come sono salvati, cosa che un .dump può troncare.
Da quali versioni di SQLite può provenire il dump?
File di database da SQLite 3.0 in poi, in UTF-8 o UTF-16, e dump del .dump della shell sqlite3 o di iterdump() di Python. Ogni file e dump di test viene da sqlite3 dalla 3.31 alla 3.54, tabelle STRICT e WITHOUT ROWID incluse, ed è confrontato con la sorgente cella per cella.
Come vengono decisi i tipi di colonna se SQLite non li applica?
Ogni colonna mantiene il suo tipo dichiarato, e così COLLATE NOCASE e RTRIM. STRICT viene escluso, così lo script si carica su ogni versione dalla 3.31.
INTEGER PRIMARY KEY e AUTOINCREMENT vengono mantenuti?
Sì. INTEGER PRIMARY KEY e AUTOINCREMENT restano come sono, e sqlite_sequence riparte da dove l'ha lasciata il dump.
E viste e trigger?
Sono elencati per nome nel report e non vengono convertiti, così puoi ricrearli una volta caricate le tabelle.
Su quali versioni di SQLite si carica lo script?
SQLite 3.31 e successive. Ogni file e dump di test si carica su 3.31 e 3.54, fermandosi al primo errore se qualcosa va storto.