Eine SQLite-Datenbank auf ein älteres oder neueres SQLite bringen
Zieh eine SQLite-Datenbankdatei (.db, .sqlite, .sqlite3) oder das SQL, das .dump von sqlite3 schreibt, hierher und lade ein Skript herunter, das auf SQLite ab 3.31 lädt. Jede Spalte behält ihren deklarierten Typ und ihre Collation, STRICT entfällt, damit ältere Versionen die Tabellen akzeptieren, und jede Änderung steht im Bericht.
18 Zeilen konvertiert, keine Korrekturen, keine abgelehnt
Tabellen in shop_2024_sqlite.sqlSQLite-Dump · erstellt mit sqlite3 · utf-8
customers8 Zeilen
7 Spalten 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 Zeilen
9 Spalten 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
Nicht konvertiert
- Sicht order_totals
- Trigger orders_shipped
Jede Datenbank schreibt diese in ihrer eigenen Sprache. Schreib sie für SQLite neu.
-- 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;
Korrekturen
Nichts musste korrigiert werden.
Zu prüfen
- 2 Sichten, Trigger, Routinen oder Ereignisse werden nicht konvertiert; der Bericht listet sie einzeln auf. Lege sie in SQLite von Hand neu an.
Deine Datei wird auf diesem Computer umgewandelt und nie hochgeladen.
Weitere Beispiele:
Was sich zwischen Datei und Skript ändert
Jede Zeile ist eine Regel, die der Konverter anwendet, mit der Berichtszeile, die er schreibt, wenn die Regel etwas an deinen Daten ändert.
declared types (any text: VARCHAR(255), DATETIME, BOOLEAN, JSON or none)
der Typ, in den jeder Wert der Spalte passt
Dieselben deklarierten Typen, daher laden die Werte so, wie sie gespeichert waren.
BOOLEAN, BOOL
INTEGER 0 oder 1 mit einem CHECK
Wenn jeder Wert 0 oder 1 ist; eine Spalte, die auch andere Werte enthält, behält sie als Zahlen oder Text.
TEXT, VARCHAR(n), CHAR(n), CLOB
der deklarierte Typ, unverändert
SQLite erzwingt keine Länge; eine deklarierte Länge gilt nur, wenn jeder Wert hineinpasst.
DECIMAL(p,s), NUMERIC
der exakte Typ, wenn jeder Wert hineinpasst, sonst ein double
SQLite speichert sie als Ganzzahlen oder doubles; eine deklarierte Genauigkeit gilt nur, wenn die Werte hineinpassen.
BLOB, and columns holding bytes
BLOB
Bytes bleiben Bytes; Text und Zahlen in derselben Spalte bleiben als ihre Bytes erhalten.
DATE, DATETIME, TIMESTAMP holding ISO 8601 text
DATE, DATETIME als ISO-8601-Text
Wenn jeder Wert ein Datum oder ein Datum mit Uhrzeit ist; Epoch-Zahlen und anderer Text behalten ihre Werte unverändert.
JSON holding JSON text
TEXT
Wenn jeder Wert ein JSON-Objekt oder -Array ist.
Infinity in REAL columns
9e999, das eigene Unendlich von SQLite
SQLite schreibt Unendlich als überlaufendes Literal, das wieder als Unendlich lädt.
INTEGER PRIMARY KEY, AUTOINCREMENT
INTEGER PRIMARY KEY, AUTOINCREMENT beibehalten
Nur eine Spalte, die genau als INTEGER PRIMARY KEY deklariert ist, ist die rowid; jede Zeile behält ihre ID, und der Zähler beginnt nach der höchsten je vergebenen ID.
COLLATE NOCASE
COLLATE NOCASE
Dieselbe Collation.
generated columns
generierte Spalten, STORED oder VIRTUAL wie in der Quelle
SQLite berechnet sie auf dieselbe Weise.
generated columns with functions IntoSQL doesn't write, and the || operator
eine normale Spalte
Eine Formel, die sich nicht schreiben lässt, hinterlässt eine normale Spalte und eine Zeile im Bericht; der Dump enthält keine Werte für generierte Spalten.
Berichtszeile: generated_not_translated
defaults with functions IntoSQL doesn't write (strftime, randomblob)
kein Standardwert
Ein Standardwert, der sich nicht schreiben lässt, wird weggelassen und gemeldet; CURRENT_TIMESTAMP und datetime('now') werden geschrieben.
Berichtszeile: default_not_translated
CHECK constraints
übersetzt
Dieselben CHECK-Bedingungen, geprüft beim Laden jeder Zeile.
CHECK constraints with functions IntoSQL doesn't write
nicht angelegt
Eine CHECK-Bedingung, die sich nicht schreiben lässt, wird weggelassen und gemeldet.
Berichtszeile: check_skipped
partial and expression indexes
nicht angelegt
IntoSQL schreibt Indizes auf ganze Spalten; lege die anderen nach dem Laden neu an.
Berichtszeile: index_skipped
foreign keys (unenforced unless PRAGMA foreign_keys=ON)
dieselben Fremdschlüssel, aufgelistet von PRAGMA foreign_key_check
SQLite prüft Fremdschlüssel nur auf Anweisung, daher sind Zeilen ohne Elternzeile häufig: Sie laden, und der Schlüssel bleibt mit einer Warnung ungeprüft, statt das Laden abzubrechen.
foreign keys to tables the dump doesn't create
nicht angelegt
Ein Schlüssel kann nicht auf eine Tabelle verweisen, die es nicht gibt.
Berichtszeile: foreign_key_skipped
primary keys holding NULL, and NOT NULL columns with values that become NULL
NOT NULL entfernt
SQLite erlaubt NULL in einem Primärschlüssel, der nicht die rowid ist; die Spalte kann im Ziel nicht NOT NULL sein, sonst würde das Laden abbrechen.
Berichtszeile: not_null_relaxed
views, triggers and virtual tables (FTS, R*Tree)
im Bericht aufgeführt
Ihr Code ist in der eigenen Sprache von SQLite geschrieben, und virtuelle Tabellen brauchen die Module von SQLite; sie werden aufgeführt, damit du sie neu anlegst. Ihre internen Tabellen werden nicht kopiert.
Berichtszeile: not_converted_objects
dumps without CREATE TABLE (--data-only)
Typen aus den Werten gelesen
Ein Dump nur mit Daten enthält nur Zeilen, daher kommen die Typen aus den Werten, und die Spalten werden nummeriert.
Berichtszeile: no_schema
expressions in INSERT values other than the text functions dumps write
NULL
unistr(), replace(), char() und || werden so ausgewertet, wie die Shell sie schreibt; andere Ausdrücke lassen sich ohne Datenbank nicht auswerten.
Berichtszeile: expression_value
NUL characters in text
beibehalten
Die sqlite3-Shell und Python schneiden Text beim Dumpen an einem NUL-Zeichen ab, daher steht nur, was davor kommt, im Dump.
text that isn't valid UTF-8
die fehlerhaften Bytes als Ersatzzeichen
Dumps schreiben solchen Text als rohe Bytes; das Skript ist UTF-8.
Berichtszeile: invalid_utf8_replaced
text decoded twice (ñ)
unverändert kopiert
Der Dump enthält genau diese Zeichen, daher werden sie kopiert; der Bericht weist auf sie hin.
Berichtszeile: mojibake_suspected
| In der Datei | Im Skript | Berichtszeile |
|---|---|---|
| declared types (any text: VARCHAR(255), DATETIME, BOOLEAN, JSON or none) | der Typ, in den jeder Wert der Spalte passtDieselben deklarierten Typen, daher laden die Werte so, wie sie gespeichert waren. | |
| BOOLEAN, BOOL | INTEGER 0 oder 1 mit einem CHECKWenn jeder Wert 0 oder 1 ist; eine Spalte, die auch andere Werte enthält, behält sie als Zahlen oder Text. | |
| TEXT, VARCHAR(n), CHAR(n), CLOB | der deklarierte Typ, unverändertSQLite erzwingt keine Länge; eine deklarierte Länge gilt nur, wenn jeder Wert hineinpasst. | |
| DECIMAL(p,s), NUMERIC | der exakte Typ, wenn jeder Wert hineinpasst, sonst ein doubleSQLite speichert sie als Ganzzahlen oder doubles; eine deklarierte Genauigkeit gilt nur, wenn die Werte hineinpassen. | |
| BLOB, and columns holding bytes | BLOBBytes bleiben Bytes; Text und Zahlen in derselben Spalte bleiben als ihre Bytes erhalten. | |
| DATE, DATETIME, TIMESTAMP holding ISO 8601 text | DATE, DATETIME als ISO-8601-TextWenn jeder Wert ein Datum oder ein Datum mit Uhrzeit ist; Epoch-Zahlen und anderer Text behalten ihre Werte unverändert. | |
| JSON holding JSON text | TEXTWenn jeder Wert ein JSON-Objekt oder -Array ist. | |
| Infinity in REAL columns | 9e999, das eigene Unendlich von SQLiteSQLite schreibt Unendlich als überlaufendes Literal, das wieder als Unendlich lädt. | |
| INTEGER PRIMARY KEY, AUTOINCREMENT | INTEGER PRIMARY KEY, AUTOINCREMENT beibehaltenNur eine Spalte, die genau als INTEGER PRIMARY KEY deklariert ist, ist die rowid; jede Zeile behält ihre ID, und der Zähler beginnt nach der höchsten je vergebenen ID. | |
| COLLATE NOCASE | COLLATE NOCASEDieselbe Collation. | |
| generated columns | generierte Spalten, STORED oder VIRTUAL wie in der QuelleSQLite berechnet sie auf dieselbe Weise. | |
| generated columns with functions IntoSQL doesn't write, and the || operator | eine normale SpalteEine Formel, die sich nicht schreiben lässt, hinterlässt eine normale Spalte und eine Zeile im Bericht; der Dump enthält keine Werte für generierte Spalten. | generated_not_translated |
| defaults with functions IntoSQL doesn't write (strftime, randomblob) | kein StandardwertEin Standardwert, der sich nicht schreiben lässt, wird weggelassen und gemeldet; CURRENT_TIMESTAMP und datetime('now') werden geschrieben. | default_not_translated |
| CHECK constraints | übersetztDieselben CHECK-Bedingungen, geprüft beim Laden jeder Zeile. | |
| CHECK constraints with functions IntoSQL doesn't write | nicht angelegtEine CHECK-Bedingung, die sich nicht schreiben lässt, wird weggelassen und gemeldet. | check_skipped |
| partial and expression indexes | nicht angelegtIntoSQL schreibt Indizes auf ganze Spalten; lege die anderen nach dem Laden neu an. | index_skipped |
| foreign keys (unenforced unless PRAGMA foreign_keys=ON) | dieselben Fremdschlüssel, aufgelistet von PRAGMA foreign_key_checkSQLite prüft Fremdschlüssel nur auf Anweisung, daher sind Zeilen ohne Elternzeile häufig: Sie laden, und der Schlüssel bleibt mit einer Warnung ungeprüft, statt das Laden abzubrechen. | |
| foreign keys to tables the dump doesn't create | nicht angelegtEin Schlüssel kann nicht auf eine Tabelle verweisen, die es nicht gibt. | foreign_key_skipped |
| primary keys holding NULL, and NOT NULL columns with values that become NULL | NOT NULL entferntSQLite erlaubt NULL in einem Primärschlüssel, der nicht die rowid ist; die Spalte kann im Ziel nicht NOT NULL sein, sonst würde das Laden abbrechen. | not_null_relaxed |
| views, triggers and virtual tables (FTS, R*Tree) | im Bericht aufgeführtIhr Code ist in der eigenen Sprache von SQLite geschrieben, und virtuelle Tabellen brauchen die Module von SQLite; sie werden aufgeführt, damit du sie neu anlegst. Ihre internen Tabellen werden nicht kopiert. | not_converted_objects |
| dumps without CREATE TABLE (--data-only) | Typen aus den Werten gelesenEin Dump nur mit Daten enthält nur Zeilen, daher kommen die Typen aus den Werten, und die Spalten werden nummeriert. | no_schema |
| expressions in INSERT values other than the text functions dumps write | NULLunistr(), replace(), char() und || werden so ausgewertet, wie die Shell sie schreibt; andere Ausdrücke lassen sich ohne Datenbank nicht auswerten. | expression_value |
| NUL characters in text | beibehaltenDie sqlite3-Shell und Python schneiden Text beim Dumpen an einem NUL-Zeichen ab, daher steht nur, was davor kommt, im Dump. | |
| text that isn't valid UTF-8 | die fehlerhaften Bytes als ErsatzzeichenDumps schreiben solchen Text als rohe Bytes; das Skript ist UTF-8. | invalid_utf8_replaced |
| text decoded twice (ñ) | unverändert kopiertDer Dump enthält genau diese Zeichen, daher werden sie kopiert; der Bericht weist auf sie hin. | mojibake_suspected |
Das Skript in SQLite laden
Das Skript legt die Tabellen an, kopiert die Zeilen und fügt dann Schlüssel, Indizes und Fremdschlüssel hinzu, so lädt es schnell und hält beim ersten Fehler an.
sqlite3 -bail mydb.sqlite < sqlite.sqlite.sqlFremdschlüssel werden in jeder Tabelle deklariert, und die Zeilen laden mit ausgeschalteter Fremdschlüsselprüfung. Danach listet das Skript jede Zeile auf, die auf eine nicht vorhandene Zeile verweist, statt auf halbem Weg abzubrechen.
Lade einen großen Dump in eine neue Datei auf einer lokalen Festplatte. Das Skript lädt alles in einer Transaktion ohne Synchronisierung, so läuft es mit Festplattengeschwindigkeit, und ein abgebrochenes Laden hinterlässt keine halben Tabellen.
Die Kommandozeile lädt die Datei direkt in eine SQLite-Datenbank, ohne ein Skript zu schreiben. Das ist kostenlos.
Den SQLite-Dump für das beste Ergebnis erstellen
Der Konverter liest, was der Dump enthält. Mit diesen Optionen bleibt mehr von deinen Daten darin:
- Die Datenbankdatei selbst wird unverändert konvertiert und Seite für Seite in deinem Browser gelesen. Schließe zuerst die App, die in sie schreibt, damit keine Änderung in ihrer -wal-Datei zurückbleibt.
- sqlite3 app.db .dump > app.sql schreibt dieselbe Datenbank als SQL, das sich ebenfalls konvertieren lässt, als .sql oder .sql.gz.
- DB Browser for SQLite schreibt dieses SQL mit File, Export, Database to SQL file, und iterdump() in Python ebenso.
Was nicht konvertiert wird
Views, Trigger, Prozeduren, Funktionen und andere Objekte in der eigenen Sprache von SQLite stehen mit Namen im Bericht und werden nie stillschweigend entfernt, damit du jedes vor dem Neuanlegen mit der SQLite-Version abgleichen kannst, in die du lädst.
Fragen zum Wechsel von SQLite zwischen Versionen
Keine Antwort gefunden? Schreib uns über die Kontaktseite, und ein Mensch antwortet. Kontaktseite
Wird mein Dump hochgeladen?
Nein. Der Konverter läuft in deinem Browser und liest den Dump stückweise von deiner Festplatte, daher verlässt er nie deinen Computer. Die Desktop-App und die Kommandozeile konvertieren ebenfalls auf deinem Computer.
Wie groß darf der Dump sein?
Der Konverter hält nie den ganzen Dump im Speicher: Er liest die Datei zweimal, in Abschnitten, und schreibt das Skript fortlaufend. Dumps von mehreren Gigabyte werden im Browser, in der Desktop-App und mit der Kommandozeile konvertiert.
Kann ich die .db-Datei selbst konvertieren?
Ja. Leg die .db-, .sqlite- oder .sqlite3-Datei ab: Sie wird in deinem Browser gelesen und nie hochgeladen. Text mit NUL-Zeichen und jede Ziffer eines double kommen so an, wie sie gespeichert sind, was ein .dump abschneiden kann.
Aus welchen SQLite-Versionen kann der Dump stammen?
Datenbankdateien ab SQLite 3.0, in UTF-8 oder UTF-16, und Dumps aus .dump der sqlite3-Shell oder aus iterdump() in Python. Jede Testdatei und jeder Test-Dump stammt aus sqlite3 3.31 bis 3.54, einschließlich STRICT- und WITHOUT ROWID-Tabellen, und wird Zelle für Zelle mit seiner Quelle verglichen.
Wie werden Spaltentypen bestimmt, wenn SQLite sie nicht erzwingt?
Jede Spalte behält ihren deklarierten Typ, ebenso COLLATE NOCASE und RTRIM. STRICT wird weggelassen, damit das Skript auf jeder Version ab 3.31 lädt.
Bleiben INTEGER PRIMARY KEY und AUTOINCREMENT erhalten?
Ja. INTEGER PRIMARY KEY und AUTOINCREMENT bleiben, wie sie sind, und sqlite_sequence macht dort weiter, wo der Dump aufgehört hat.
Was ist mit Sichten und Triggern?
Sie stehen mit Namen im Bericht und werden nicht konvertiert, damit du sie neu anlegen kannst, sobald die Tabellen da sind.
Auf welchen SQLite-Versionen lädt das Skript?
SQLite 3.31 und neuer. Jede Testdatei und jeder Test-Dump lädt auf 3.31 und 3.54 und hält beim ersten Fehler an, falls etwas schiefgeht.