SQLite-Erweiterung
Die SQLite-Erweiterung ermöglicht DuckDB, Daten direkt aus einer SQLite-Datenbankdatei zu lesen und zu schreiben. Die Daten können direkt aus den zugrunde liegenden SQLite-Tabellen abgefragt werden. Daten können aus SQLite-Tabellen in DuckDB-Tabellen geladen werden oder umgekehrt.
Installation und Laden
Die sqlite-Erweiterung wird beim ersten Gebrauch transparent aus dem offiziellen Erweiterungs-Repository automatisch geladen.
Wenn Sie sie manuell installieren und laden möchten, führen Sie aus:
INSTALL sqlite;LOAD sqlite;Verwendung
Damit eine SQLite-Datei für DuckDB zugänglich ist, verwenden Sie die Anweisung ATTACH mit dem Typ sqlite oder sqlite_scanner. Angehängte SQLite-Datenbanken unterstützen Lese- und Schreiboperationen.
Um sich beispielsweise mit der Datei sakila.db zu verbinden, führen Sie aus:
ATTACH 'sakila.db' (TYPE sqlite);USE sakila;Die Tabellen in der Datei können gelesen werden, als wären sie normale DuckDB-Tabellen, die zugrunde liegenden Daten werden jedoch zur Abfragezeit direkt aus den SQLite-Tabellen in der Datei gelesen.
SHOW TABLES;| name |
|---|
| actor |
| address |
| category |
| city |
| country |
| customer |
| customer_list |
| film |
| film_actor |
| film_category |
| film_list |
| film_text |
| inventory |
| language |
| payment |
| rental |
| sales_by_film_category |
| sales_by_store |
| staff |
| staff_list |
| store |
Sie können die Tabellen mit SQL abfragen, z. B. mit den Beispielabfragen aus sakila-examples.sql:
SELECT cat.name AS category_name, sum(ifnull(pay.amount, 0)) AS revenueFROM category catLEFT JOIN film_category flm_cat ON cat.category_id = flm_cat.category_idLEFT JOIN film fil ON flm_cat.film_id = fil.film_idLEFT JOIN inventory inv ON fil.film_id = inv.film_idLEFT JOIN rental ren ON inv.inventory_id = ren.inventory_idLEFT JOIN payment pay ON ren.rental_id = pay.rental_idGROUP BY cat.nameORDER BY revenue DESCLIMIT 5;Datentypen
SQLite ist ein schwach typisiertes Datenbanksystem. Beim Speichern von Daten in einer SQLite-Tabelle werden Typen daher nicht erzwungen. Das folgende SQL ist in SQLite gültig:
CREATE TABLE numbers (i INTEGER);INSERT INTO numbers VALUES ('hello');DuckDB ist ein stark typisiertes Datenbanksystem und verlangt daher, dass alle Spalten definierte Typen haben; das System prüft Daten rigoros auf Korrektheit.
Beim Abfragen von SQLite muss DuckDB eine konkrete Spaltentypzuordnung ableiten. DuckDB folgt den Type-Affinity-Regeln von SQLite mit einigen Erweiterungen.
- Enthält der deklarierte Typ den String
INT, wird er in den TypBIGINTübersetzt - Enthält der deklarierte Typ der Spalte einen der Strings
CHAR,CLOBoderTEXT, wird er inVARCHARübersetzt. - Enthält der deklarierte Typ einer Spalte den String
BLOBoder ist kein Typ angegeben, wird er inBLOBübersetzt. - Enthält der deklarierte Typ einer Spalte einen der Strings
REAL,FLOA,DOUB,DECoderNUM, wird er inDOUBLEübersetzt. - Ist der deklarierte Typ
DATE, wird er inDATEübersetzt. - Enthält der deklarierte Typ den String
TIME, wird er inTIMESTAMPübersetzt. - Trifft nichts der oben genannten zu, wird er in
VARCHARübersetzt.
Da DuckDB erzwingt, dass die entsprechenden Spalten nur korrekt typisierte Werte enthalten, können wir den String „hello“ nicht in eine Spalte vom Typ BIGINT laden. Beim Lesen aus der Tabelle „numbers“ oben wird daher ein Fehler geworfen:
Mismatch Type Error: Invalid type in column "i": column was declared as integer, found "hello" of type "text" instead.Dieser Fehler kann vermieden werden, indem die Option sqlite_all_varchar gesetzt wird:
SET GLOBAL sqlite_all_varchar = true;Wenn gesetzt, überschreibt diese Option die oben beschriebenen Typkonvertierungsregeln und konvertiert die SQLite-Spalten stattdessen immer in eine VARCHAR-Spalte. Beachten Sie, dass diese Einstellung vor dem Aufruf von sqlite_attach gesetzt werden muss.
SQLite-Datenbanken direkt öffnen
SQLite-Datenbanken können auch direkt geöffnet und transparent anstelle einer DuckDB-Datenbankdatei verwendet werden. In jedem Client kann beim Verbinden ein Pfad zu einer SQLite-Datenbankdatei angegeben werden, woraufhin die SQLite-Datenbank geöffnet wird.
Mit der Shell kann eine SQLite-Datenbank beispielsweise wie folgt geöffnet werden:
duckdb sakila.dbSELECT first_nameFROM actorLIMIT 3;| first_name |
|---|
| PENELOPE |
| NICK |
| ED |
Daten nach SQLite schreiben
Zusätzlich zum Lesen von Daten aus SQLite ermöglicht die Erweiterung das Erstellen neuer SQLite-Datenbankdateien, das Erstellen von Tabellen, das Laden von Daten in SQLite und andere Änderungen an SQLite-Datenbankdateien mit Standard-SQL-Abfragen.
Damit können Sie DuckDB beispielsweise verwenden, um in einer SQLite-Datenbank gespeicherte Daten nach Parquet zu exportieren oder Daten aus einer Parquet-Datei in SQLite zu lesen.
Nachfolgend ein kurzes Beispiel, wie Sie eine neue SQLite-Datenbank erstellen und Daten darin laden.
ATTACH 'new_sqlite_database.db' AS sqlite_db (TYPE sqlite);CREATE TABLE sqlite_db.tbl (id INTEGER, name VARCHAR);INSERT INTO sqlite_db.tbl VALUES (42, 'DuckDB');Die resultierende SQLite-Datenbank kann dann aus SQLite gelesen werden.
sqlite3 new_sqlite_database.dbSQLite version 3.39.5 2022-10-14 20:58:05sqlite> SELECT * FROM tbl;id name-- ------42 DuckDBViele Operationen auf SQLite-Tabellen werden unterstützt. Alle diese Operationen ändern die SQLite-Datenbank direkt, und das Ergebnis nachfolgender Operationen kann dann mit SQLite gelesen werden.
Nebenläufigkeit
DuckDB kann eine SQLite-Datenbank lesen oder ändern, während DuckDB oder SQLite dieselbe Datenbank aus einem anderen Thread oder einem separaten Prozess liest oder ändert. Mehr als ein Thread oder Prozess kann die SQLite-Datenbank gleichzeitig lesen, aber nur ein einzelner Thread oder Prozess kann zu einem Zeitpunkt in die Datenbank schreiben. Die Datenbanksperre wird von der SQLite-Bibliothek verwaltet, nicht von DuckDB. Innerhalb desselben Prozesses verwendet SQLite Mutexes. Beim Zugriff aus verschiedenen Prozessen verwendet SQLite Dateisystemsperren. Die Sperrmechanismen hängen auch von der SQLite-Konfiguration ab, etwa vom WAL-Modus. Weitere Informationen finden Sie in der SQLite-Dokumentation zu Locking.
Warning Das Linken mehrerer Kopien der SQLite-Bibliothek in dieselbe Anwendung kann zu Anwendungsfehlern führen. Weitere Informationen finden Sie in sqlite_scanner Issue #82.
Einstellungen
Die Erweiterung stellt die folgenden Konfigurationsparameter bereit.
| Name | Beschreibung | Standard |
|---|---|---|
sqlite_debug_show_queries |
DEBUG-EINSTELLUNG: alle an SQLite gesendeten Abfragen auf stdout ausgeben | false |
Unterstützte Operationen
Nachfolgend eine Liste unterstützter Operationen.
CREATE TABLE
CREATE TABLE sqlite_db.tbl (id INTEGER, name VARCHAR);INSERT INTO
INSERT INTO sqlite_db.tbl VALUES (42, 'DuckDB');SELECT
SELECT * FROM sqlite_db.tbl;| id | name |
|---|---|
| 42 | DuckDB |
COPY
COPY sqlite_db.tbl TO 'data.parquet';COPY sqlite_db.tbl FROM 'data.parquet';UPDATE
UPDATE sqlite_db.tbl SET name = 'Woohoo' WHERE id = 42;DELETE
DELETE FROM sqlite_db.tbl WHERE id = 42;ALTER TABLE
ALTER TABLE sqlite_db.tbl ADD COLUMN k INTEGER;DROP TABLE
DROP TABLE sqlite_db.tbl;CREATE VIEW
CREATE VIEW sqlite_db.v1 AS SELECT 42;Transaktionen
CREATE TABLE sqlite_db.tmp (i INTEGER);BEGIN;INSERT INTO sqlite_db.tmp VALUES (42);SELECT * FROM sqlite_db.tmp;| i |
|---|
| 42 |
ROLLBACK;SELECT * FROM sqlite_db.tmp;| i |
|---|
Deprecated Die alte Funktion
sqlite_attachist veraltet. Es wird empfohlen, auf die neueATTACH-Syntax umzusteigen.
Kompatibilität
Die SQLite-Erweiterung kann Datenbanken lesen, die von Turso geschrieben wurden, einer Rust-Neuimplementierung von SQLite.