Zum Inhalt springen

Jupyter-Notebooks

Der Python-Client von DuckDB kann in Jupyter-Notebooks ohne zusätzliche Konfiguration direkt verwendet werden. Zusätzliche Bibliotheken können jedoch die Entwicklung von SQL-Abfragen vereinfachen. Dieser Leitfaden beschreibt, wie Sie diese zusätzlichen Bibliotheken nutzen. Weitere Leitfäden im Python-Bereich zeigen, wie DuckDB und Python zusammenarbeiten.

In diesem Beispiel verwenden wir das Paket JupySQL. Dieser Beispiel-Workflow ist auch als Google-Colab-Notebook verfügbar.

Bibliotheken installieren

Vier zusätzliche Bibliotheken verbessern die DuckDB-Erfahrung in Jupyter-Notebooks.

  1. jupysql: Wandelt eine Jupyter-Codezelle in eine SQL-Zelle um
  2. Pandas: Übersichtliche Tabellenvisualisierungen und Kompatibilität mit weiteren Analysen
  3. matplotlib: Plotten mit Python
  4. duckdb-engine (DuckDB-SQLAlchemy-Treiber): Wird von SQLAlchemy verwendet, um eine Verbindung zu DuckDB herzustellen (optional)

Führen Sie diese pip install-Befehle in der Kommandozeile aus, falls Jupyter Notebook noch nicht installiert ist. Andernfalls finden Sie im oben genannten Google-Colab-Link ein Beispiel direkt im Notebook:

Terminal window
pip install duckdb

Jupyter Notebook installieren:

Terminal window
pip install notebook

Oder JupyterLab:

Terminal window
pip install jupyterlab

Unterstützende Bibliotheken installieren:

Terminal window
pip install jupysql pandas matplotlib duckdb-engine

Bibliotheken importieren und konfigurieren

Öffnen Sie ein Jupyter-Notebook und importieren Sie die relevanten Bibliotheken.

Setzen Sie die jupysql-Konfiguration so, dass Daten direkt nach Pandas ausgegeben werden und die im Notebook angezeigte Ausgabe vereinfacht wird.

%config SqlMagic.autopandas = True
%config SqlMagic.feedback = False
%config SqlMagic.displaycon = False

Nativ mit DuckDB verbinden

Um eine Verbindung zu DuckDB herzustellen, führen Sie aus:

import duckdb
import pandas as pd
%load_ext sql
conn = duckdb.connect()
%sql conn --alias duckdb

Warnung Variablen werden in einer nativen DuckDB-Verbindung nicht erkannt.

Über SQLAlchemy mit DuckDB verbinden

Alternativ können Sie über SQLAlchemy mit duckdb_engine eine Verbindung zu DuckDB herstellen. Siehe die Unterschiede bei Leistung und Funktionen.

import duckdb
import pandas as pd
# No need to import duckdb_engine
# jupysql will auto-detect the driver needed based on the connection string!
# Import jupysql Jupyter extension to create SQL cells
%load_ext sql

Verbinden Sie entweder eine neue In-Memory-DuckDB, die Standardverbindung oder eine dateibasierte Datenbank:

%sql duckdb:///:memory:
%sql duckdb:///:default:
%sql duckdb:///path/to/file.db

Der Befehl %sql und duckdb.sql teilen sich dieselbe Standardverbindung, wenn Sie duckdb:///:default: als SQLAlchemy-Verbindungszeichenfolge angeben.

DuckDB abfragen

Einzeilige SQL-Abfragen können mit %sql am Zeilenanfang ausgeführt werden. Die Abfrageergebnisse werden als Pandas-DataFrame angezeigt.

%sql SELECT 'Off and flying!' AS a_duckdb_column;

Eine gesamte Jupyter-Zelle kann als SQL-Zelle verwendet werden, indem Sie %%sql an den Anfang der Zelle setzen. Die Abfrageergebnisse werden als Pandas-DataFrame angezeigt.

%%sql
SELECT
schema_name,
function_name
FROM duckdb_functions()
ORDER BY ALL DESC
LIMIT 5;

Um die Abfrageergebnisse in einer Python-Variable zu speichern, verwenden Sie << als Zuweisungsoperator. Das funktioniert sowohl mit den Jupyter-Magics %sql als auch %%sql.

%sql res << SELECT 'Off and flying!' AS a_duckdb_column;

Wenn die Option %config SqlMagic.autopandas = True gesetzt ist, ist die Variable ein Pandas-DataFrame, andernfalls ein ResultSet, das sich mit der Funktion DataFrame() nach Pandas umwandeln lässt.

Pandas-DataFrames abfragen

DuckDB kann jedes DataFrame finden und abfragen, das als Variable im Jupyter-Notebook gespeichert ist.

input_df = pd.DataFrame.from_dict({"i": [1, 2, 3],
"j": ["one", "two", "three"]})

Das abzufragende DataFrame kann wie jede andere Tabelle in der FROM-Klausel angegeben werden.

%sql output_df << SELECT sum(i) AS total_i FROM input_df;

Warnung Wenn Sie die SQLAlchemy-Verbindung verwenden, führen Sie %sql SET python_scan_all_frames=true aus, damit Pandas-DataFrames abfragbar sind.

DuckDB-Daten visualisieren

Der übliche Weg, Datensätze in Python zu plotten, besteht darin, sie mit Pandas zu laden und anschließend matplotlib oder seaborn zum Plotten zu verwenden. Dieser Ansatz lädt alle Daten in den Speicher und ist daher sehr ineffizient. Das Plotting-Modul in JupySQL führt Berechnungen in der SQL-Engine aus. Dadurch übernimmt die Engine die Speicherverwaltung, Zwischenberechnungen belasten den Speicher nicht weiter, und auch sehr große Datensätze lassen sich effizient plotten.

Boxplot und Histogramm

Um einen Boxplot zu erstellen, rufen Sie %sqlplot boxplot auf und übergeben den Tabellennamen sowie die zu plottende Spalte. In diesem Fall ist der Tabellenname der Pfad der lokal gespeicherten Parquet-Datei.

from urllib.request import urlretrieve
_ = urlretrieve(
"https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet",
"yellow_tripdata_2021-01.parquet",
)
%sqlplot boxplot --table yellow_tripdata_2021-01.parquet --column trip_distance

Boxplot der Spalte trip_distance

DuckDB-httpfs-Extension installieren und laden

Die httpfs-Extension von DuckDB ermöglicht das entfernte Abfragen von Parquet- und CSV-Dateien über HTTP. Diese Beispiele fragen eine Parquet-Datei mit historischen Taxidaten aus NYC ab. Durch das Parquet-Format zieht DuckDB nur die benötigten Zeilen und Spalten in den Speicher, statt die gesamte Datei herunterzuladen. DuckDB kann auch lokale Parquet-Dateien verarbeiten, was sinnvoll sein kann, wenn die gesamte Parquet-Datei abgefragt wird oder mehrere Abfragen große Teilmengen der Datei benötigen.

%%sql
INSTALL httpfs;
LOAD httpfs;

Erstellen Sie nun eine Abfrage, die nach dem 90. Perzentil filtert. Beachten Sie die Funktionen --save und --no-execute. Damit speichert JupySQL die Abfrage, führt sie aber nicht aus. Sie wird im nächsten Plot-Aufruf referenziert.

%%sql --save short_trips --no-execute
SELECT *
FROM 'https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet'
WHERE trip_distance < 6.3

Um ein Histogramm zu erstellen, rufen Sie %sqlplot histogram auf und übergeben den Tabellennamen, die zu plottende Spalte und die Anzahl der Bins. Hier wird --with short-trips verwendet, damit JupySQL die zuvor definierte Abfrage nutzt und nur eine Teilmenge der Daten plottet.

%sqlplot histogram --table short_trips --column trip_distance --bins 10 --with short_trips

Histogramm der Spalte trip_distance

Zusammenfassung

Sie können jetzt einfach und performant zwischen SQL und Pandas wechseln. Sehr große Datensätze lassen sich direkt über die Engine plotten (ohne die gesamte Datei herunterzuladen und vollständig in Pandas in den Speicher zu laden). DataFrames können in SQL als Tabellen gelesen werden, und SQL-Ergebnisse können in DataFrames ausgegeben werden. Viel Erfolg bei der Analyse!

Eine Alternative zu jupysql ist magic_duckdb.