Zum Inhalt springen

SQL auf Apache Arrow

DuckDB kann mehrere verschiedene Typen von Apache-Arrow-Objekten abfragen.

Apache Arrow Tables

Arrow Tables, die in lokalen Variablen gespeichert sind, können abgefragt werden, als wären sie normale Tabellen in DuckDB.

import duckdb
import pyarrow as pa
# connect to an in-memory database
con = duckdb.connect()
my_arrow_table = pa.Table.from_pydict({'i': [1, 2, 3, 4],
'j': ["one", "two", "three", "four"]})
# query the Apache Arrow Table "my_arrow_table" and return as an Arrow Table
results = con.execute("SELECT * FROM my_arrow_table WHERE i = 2").to_arrow_table()

Apache Arrow Datasets

Arrow Datasets, die als Variablen gespeichert sind, können ebenfalls abgefragt werden, als wären sie normale Tabellen. Datasets eignen sich, um auf Verzeichnisse mit Parquet-Dateien zu zeigen und so große Datensätze zu analysieren. DuckDB schiebt Spaltenauswahl und Zeilenfilter in die Dataset-Scan-Operation, sodass nur die benötigten Daten in den Speicher geladen werden.

import duckdb
import pyarrow as pa
import tempfile
import pathlib
import pyarrow.parquet as pq
import pyarrow.dataset as ds
# connect to an in-memory database
con = duckdb.connect()
my_arrow_table = pa.Table.from_pydict({'i': [1, 2, 3, 4],
'j': ["one", "two", "three", "four"]})
# create example Parquet files and save in a folder
base_path = pathlib.Path(tempfile.gettempdir())
(base_path / "parquet_folder").mkdir(exist_ok = True)
pq.write_to_dataset(my_arrow_table, str(base_path / "parquet_folder"))
# link to Parquet files using an Arrow Dataset
my_arrow_dataset = ds.dataset(str(base_path / 'parquet_folder/'))
# query the Apache Arrow Dataset "my_arrow_dataset" and return as an Arrow Table
results = con.execute("SELECT * FROM my_arrow_dataset WHERE i = 2").to_arrow_table()

Apache Arrow Scanners

Arrow Scanners, die als Variablen gespeichert sind, können ebenfalls abgefragt werden, als wären sie normale Tabellen. Scanner lesen ein Dataset und wählen bestimmte Spalten aus oder wenden zeilenweise Filterung an. Das ähnelt dem Pushdown von Spaltenauswahl und Filtern durch DuckDB in ein Arrow-Dataset, verwendet aber Arrow-Compute-Operationen. Arrow kann asynchrones I/O nutzen, um schnell auf Dateien zuzugreifen.

import duckdb
import pyarrow as pa
import tempfile
import pathlib
import pyarrow.parquet as pq
import pyarrow.dataset as ds
import pyarrow.compute as pc
# connect to an in-memory database
con = duckdb.connect()
my_arrow_table = pa.Table.from_pydict({'i': [1, 2, 3, 4],
'j': ["one", "two", "three", "four"]})
# create example Parquet files and save in a folder
base_path = pathlib.Path(tempfile.gettempdir())
(base_path / "parquet_folder").mkdir(exist_ok = True)
pq.write_to_dataset(my_arrow_table, str(base_path / "parquet_folder"))
# link to Parquet files using an Arrow Dataset
my_arrow_dataset = ds.dataset(str(base_path / 'parquet_folder/'))
# define the filter to be applied while scanning
# equivalent to "WHERE i = 2"
scanner_filter = (pc.field("i") == pc.scalar(2))
arrow_scanner = ds.Scanner.from_dataset(my_arrow_dataset, filter = scanner_filter)
# query the Apache Arrow scanner "arrow_scanner" and return as an Arrow Table
results = con.execute("SELECT * FROM arrow_scanner").to_arrow_table()

Apache Arrow RecordBatchReaders

Arrow RecordBatchReaders sind ein Reader für das Streaming-Binärformat von Arrow und können ebenfalls direkt abgefragt werden, als wären sie Tabellen. Dieses Streaming-Format eignet sich zum Senden von Arrow-Daten, etwa für Interprozesskommunikation oder die Kommunikation zwischen Sprachlaufzeiten.

import duckdb
import pyarrow as pa
# connect to an in-memory database
con = duckdb.connect()
my_recordbatch = pa.RecordBatch.from_pydict({'i': [1, 2, 3, 4],
'j': ["one", "two", "three", "four"]})
my_recordbatchreader = pa.ipc.RecordBatchReader.from_batches(my_recordbatch.schema, [my_recordbatch])
# query the Apache Arrow RecordBatchReader "my_recordbatchreader" and return as an Arrow Table
results = con.execute("SELECT * FROM my_recordbatchreader WHERE i = 2").to_arrow_table()