Installation
可以使用pip安装DuckDB Python API:pip install duckdb
。详情请参阅安装页面。也可以使用conda安装DuckDB:conda install python-duckdb -c conda-forge
。
Python 版本: DuckDB 需要 Python 3.7 或更新版本。
Basic API Usage
使用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
Configuration
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")
Community Extensions
要加载社区扩展,请使用repository="community"
参数传递给install_extension
方法。
例如,安装并加载h3
社区扩展如下:
import duckdb
con = duckdb.connect()
con.install_extension("h3", repository="community")
con.load_extension("h3")
Unsigned Extensions
要加载未签名的扩展,请使用config = {"allow_unsigned_extensions": "true"}
参数传递给duckdb.connect()
方法。