DuckDB Python 客户端的最新版本是 1.3.2。
安装
DuckDB Python API 可以使用 pip 进行安装:pip install duckdb
。更多详细信息请参阅安装页面。也可以使用 conda 安装 DuckDB:conda install python-duckdb -c conda-forge
。
Python 版本:DuckDB 需要 Python 3.9 或更高版本。
基本 API 用法
使用 duckdb.sql
命令是使用 DuckDB 运行 SQL 查询最直接的方式。
import duckdb
duckdb.sql("SELECT 42").show()
这会使用存储在 Python 模块全局范围内的内存数据库来运行查询。查询结果以关系(Relation)的形式返回。关系是查询的符号表示。在获取结果或请求将其打印到屏幕之前,查询不会执行。
关系可以通过将其存储在变量中并将其用作表来在后续查询中引用。通过这种方式,可以逐步构建查询。
import duckdb
r1 = duckdb.sql("SELECT 42 AS i")
duckdb.sql("SELECT i * 2 AS k FROM r1").show()
数据输入
DuckDB 可以从各种格式(包括磁盘和内存中的数据)摄取数据。更多信息请参阅数据摄取页面。
import duckdb
duckdb.read_csv("example.csv") # read a CSV file into a Relation
duckdb.read_parquet("example.parquet") # read a Parquet file into a Relation
duckdb.read_json("example.json") # read a JSON file into a Relation
duckdb.sql("SELECT * FROM 'example.csv'") # directly query a CSV file
duckdb.sql("SELECT * FROM 'example.parquet'") # directly query a Parquet file
duckdb.sql("SELECT * FROM 'example.json'") # directly query a JSON file
DataFrames
DuckDB 可以直接查询 Pandas DataFrames、Polars DataFrames 和 Arrow 表。请注意,这些是只读的,即无法通过 INSERT
或 UPDATE
语句编辑这些表。
Pandas
要直接查询 Pandas DataFrame,请运行
import duckdb
import pandas as pd
pandas_df = pd.DataFrame({"a": [42]})
duckdb.sql("SELECT * FROM pandas_df")
┌───────┐
│ a │
│ int64 │
├───────┤
│ 42 │
└───────┘
Polars
要直接查询 Polars DataFrame,请运行
import duckdb
import polars as pl
polars_df = pl.DataFrame({"a": [42]})
duckdb.sql("SELECT * FROM polars_df")
┌───────┐
│ a │
│ int64 │
├───────┤
│ 42 │
└───────┘
PyArrow
要直接查询 PyArrow 表,请运行
import duckdb
import pyarrow as pa
arrow_table = pa.Table.from_pydict({"a": [42]})
duckdb.sql("SELECT * FROM arrow_table")
┌───────┐
│ a │
│ int64 │
├───────┤
│ 42 │
└───────┘
结果转换
DuckDB 支持将查询结果高效地转换为各种格式。更多信息请参阅结果转换页面。
import duckdb
duckdb.sql("SELECT 42").fetchall() # Python objects
duckdb.sql("SELECT 42").df() # Pandas DataFrame
duckdb.sql("SELECT 42").pl() # Polars DataFrame
duckdb.sql("SELECT 42").arrow() # Arrow Table
duckdb.sql("SELECT 42").fetchnumpy() # NumPy Arrays
将数据写入磁盘
DuckDB 支持将关系(Relation)对象直接以各种格式写入磁盘。COPY
语句也可以作为替代方案,用于通过 SQL 将数据写入磁盘。
import duckdb
duckdb.sql("SELECT 42").write_parquet("out.parquet") # Write to a Parquet file
duckdb.sql("SELECT 42").write_csv("out.csv") # Write to a CSV file
duckdb.sql("COPY (SELECT 42) TO 'out.parquet'") # Copy to a Parquet file
连接选项
应用程序可以通过 duckdb.connect()
方法打开新的 DuckDB 连接。
使用内存数据库
通过 duckdb.sql()
使用 DuckDB 时,它操作的是内存数据库,即没有表会持久化到磁盘。调用不带参数的 duckdb.connect()
方法会返回一个连接,该连接也使用内存数据库。
import duckdb
con = duckdb.connect()
con.sql("SELECT 42 AS x").show()
持久存储
duckdb.connect(dbname)
会创建一个到持久数据库的连接。写入该连接的任何数据都将持久化,并且可以通过重新连接到同一个文件(无论是从 Python 还是其他 DuckDB 客户端)来重新加载。
import duckdb
# create a connection to a file called 'file.db'
con = duckdb.connect("file.db")
# create a table and load data into it
con.sql("CREATE TABLE test (i INTEGER)")
con.sql("INSERT INTO test VALUES (42)")
# query the table
con.table("test").show()
# explicitly close the connection
con.close()
# Note: connections also closed implicitly when they go out of scope
您也可以使用上下文管理器来确保连接已关闭
import duckdb
with duckdb.connect("file.db") as con:
con.sql("CREATE TABLE test (i INTEGER)")
con.sql("INSERT INTO test VALUES (42)")
con.table("test").show()
# the context manager closes the connection automatically
配置
duckdb.connect()
接受一个 config
字典,其中可以指定配置选项。例如
import duckdb
con = duckdb.connect(config = {'threads': 1})
连接对象和模块
连接对象和 duckdb
模块可以互换使用——它们支持相同的方法。唯一的区别是,当使用 duckdb
模块时,会使用全局内存数据库。
如果您正在开发一个供他人使用的包,并在其中使用 DuckDB,建议您创建连接对象,而不是使用
duckdb
模块上的方法。这是因为duckdb
模块使用共享的全局数据库——如果在多个不同的包中使用,可能会导致难以调试的问题。
在并行 Python 程序中使用连接
DuckDBPyConnection
对象不是线程安全的。如果您想从多个线程写入同一个数据库,请使用 DuckDBPyConnection.cursor()
方法为每个线程创建一个游标。
加载和安装扩展
DuckDB 的 Python API 提供了用于安装和加载扩展的函数,它们分别执行与运行 INSTALL
和 LOAD
SQL 命令等效的操作。一个安装和加载 spatial
扩展的示例如下所示
import duckdb
con = duckdb.connect()
con.install_extension("spatial")
con.load_extension("spatial")
社区扩展
要加载社区扩展,请在 install_extension
方法中使用 repository="community"
参数。
例如,按如下方式安装并加载 h3
社区扩展
import duckdb
con = duckdb.connect()
con.install_extension("h3", repository="community")
con.load_extension("h3")
未签名扩展
要加载未签名扩展,请在 duckdb.connect()
方法中使用 config = {"allow_unsigned_extensions": "true"}
参数。