- 安装
- 文档
- 入门
- 连接
- 数据导入
- 客户端 API
- 概览
- ADBC
- C
- C++
- CLI
- Dart
- Go
- Java (JDBC)
- Julia
- Node.js (已弃用)
- Node.js (Neo)
- ODBC
- PHP
- Python
- R
- Rust
- Swift
- Wasm
- SQL
- 介绍
- 语句
- 概览
- ANALYZE
- ALTER TABLE
- ALTER VIEW
- ATTACH 和 DETACH
- CALL
- CHECKPOINT
- COMMENT ON
- COPY
- CREATE INDEX
- CREATE MACRO
- CREATE SCHEMA
- CREATE SECRET
- CREATE SEQUENCE
- CREATE TABLE
- CREATE VIEW
- CREATE TYPE
- DELETE
- DESCRIBE
- DROP
- EXPORT 和 IMPORT DATABASE
- INSERT
- LOAD / INSTALL
- PIVOT
- 性能分析
- SELECT
- SET / RESET
- SET VARIABLE
- SUMMARIZE
- 事务管理
- UNPIVOT
- UPDATE
- USE
- VACUUM
- 查询语法
- SELECT
- FROM 和 JOIN
- WHERE
- GROUP BY
- GROUPING SETS
- HAVING
- ORDER BY
- LIMIT 和 OFFSET
- SAMPLE
- 展开嵌套
- WITH
- WINDOW
- QUALIFY
- VALUES
- FILTER
- 集合操作
- 预处理语句
- 数据类型
- 表达式
- 函数
- 概览
- 聚合函数
- 数组函数
- 位字符串函数
- Blob 函数
- 日期格式化函数
- 日期函数
- 日期部分函数
- 枚举函数
- 间隔函数
- Lambda 函数
- 列表函数
- 映射函数
- 嵌套函数
- 数值函数
- 模式匹配
- 正则表达式
- 结构体函数
- 文本函数
- 时间函数
- 时间戳函数
- 带时区时间戳函数
- 联合函数
- 实用函数
- 窗口函数
- 约束
- 索引
- 元查询
- DuckDB 的 SQL 方言
- 示例
- 配置
- 扩展
- 核心扩展
- 概览
- 自动补全
- Avro
- AWS
- Azure
- Delta
- DuckLake
- 编码
- Excel
- 全文搜索
- httpfs (HTTP 和 S3)
- Iceberg
- ICU
- inet
- jemalloc
- MySQL
- PostgreSQL
- 空间
- SQLite
- TPC-DS
- TPC-H
- UI
- VSS
- 指南
- 概览
- 数据查看器
- 数据库集成
- 文件格式
- 概览
- CSV 导入
- CSV 导出
- 直接读取文件
- Excel 导入
- Excel 导出
- JSON 导入
- JSON 导出
- Parquet 导入
- Parquet 导出
- 查询 Parquet 文件
- 使用 file: 协议访问文件
- 网络和云存储
- 概览
- HTTP Parquet 导入
- S3 Parquet 导入
- S3 Parquet 导出
- S3 Iceberg 导入
- S3 Express One
- GCS 导入
- Cloudflare R2 导入
- 通过 HTTPS / S3 使用 DuckDB
- Fastly 对象存储导入
- 元查询
- ODBC
- 性能
- Python
- 安装
- 执行 SQL
- Jupyter Notebooks
- marimo Notebooks
- Pandas 上的 SQL
- 从 Pandas 导入
- 导出到 Pandas
- 从 Numpy 导入
- 导出到 Numpy
- Arrow 上的 SQL
- 从 Arrow 导入
- 导出到 Arrow
- Pandas 上的关系型 API
- 多个 Python 线程
- 与 Ibis 集成
- 与 Polars 集成
- 使用 fsspec 文件系统
- SQL 编辑器
- SQL 功能
- 代码片段
- 故障排除
- 术语表
- 离线浏览
- 操作手册
- 开发
- 内部结构
- 为什么选择 DuckDB
- 行为准则
- 发布日历
- 路线图
- 站点地图
- 在线演示
标准的 DuckDB Python API 提供了一个符合 PEP 249 中描述的 DB-API 2.0 规范 的 SQL 接口,类似于 SQLite Python API。
连接
要使用此模块,您必须首先创建一个代表数据库连接的 DuckDBPyConnection
对象。这通过 duckdb.connect
方法完成。
“config”关键字参数可用于提供一个 dict
,其中包含引用 DuckDB 可理解的设置的键值对。
内存连接
特殊值 :memory:
可用于创建内存数据库。请注意,对于内存数据库,数据不会持久化到磁盘(即,当您退出 Python 进程时,所有数据都会丢失)。
命名内存连接
特殊值 :memory:
也可以加上一个后缀名称,例如::memory:conn3
。当提供名称时,后续的 duckdb.connect
调用将创建到相同数据库的新连接,共享目录(视图、表、宏等)。
不带名称使用 :memory:
将始终创建一个新的独立数据库实例。
默认连接
默认情况下,我们创建一个(未命名)的内存数据库,它位于 duckdb
模块内部。DuckDBPyConnection
的每个方法也可用于 duckdb
模块,此连接即是这些方法所使用的。
特殊值 :default:
可用于获取此默认连接。
基于文件的连接
如果 database
是文件路径,则会建立与持久数据库的连接。如果文件不存在,则会创建该文件(文件扩展名无关紧要,可以是 .db
、.duckdb
或其他任何内容)。
read_only
连接
如果您希望以只读模式连接,可以将 read_only
标志设置为 True
。如果文件不存在,在只读模式下连接时不会创建该文件。如果多个 Python 进程希望同时访问同一个数据库文件,则需要只读模式。
import duckdb
duckdb.execute("CREATE TABLE tbl AS SELECT 42 a")
con = duckdb.connect(":default:")
con.sql("SELECT * FROM tbl")
# or
duckdb.default_connection().sql("SELECT * FROM tbl")
┌───────┐
│ a │
│ int32 │
├───────┤
│ 42 │
└───────┘
import duckdb
# to start an in-memory database
con = duckdb.connect(database = ":memory:")
# to use a database file (not shared between processes)
con = duckdb.connect(database = "my-db.duckdb", read_only = False)
# to use a database file (shared between processes)
con = duckdb.connect(database = "my-db.duckdb", read_only = True)
# to explicitly get the default connection
con = duckdb.connect(database = ":default:")
如果您想创建到现有数据库的第二个连接,可以使用 cursor()
方法。这可能很有用,例如允许并行线程独立运行查询。单个连接是线程安全的,但在查询期间会被锁定,从而在这种情况下有效地串行化数据库访问。
连接在超出作用域时或使用 close()
显式关闭时会自动关闭。一旦与数据库实例的最后一个连接关闭,该数据库实例也会关闭。
查询
可以使用连接的 execute()
方法将 SQL 查询发送到 DuckDB。查询执行后,可以使用连接的 fetchone
和 fetchall
方法检索结果。fetchall
将检索所有结果并完成事务。fetchone
每次调用将检索一行结果,直到没有更多结果可用。事务只会在调用 fetchone
且没有更多结果剩余时关闭(返回值将是 None
)。例如,在查询只返回一行的情况下,应调用一次 fetchone
以检索结果,并第二次调用以关闭事务。以下是一些简短的示例
# create a table
con.execute("CREATE TABLE items (item VARCHAR, value DECIMAL(10, 2), count INTEGER)")
# insert two items into the table
con.execute("INSERT INTO items VALUES ('jeans', 20.0, 1), ('hammer', 42.2, 2)")
# retrieve the items again
con.execute("SELECT * FROM items")
print(con.fetchall())
# [('jeans', Decimal('20.00'), 1), ('hammer', Decimal('42.20'), 2)]
# retrieve the items one at a time
con.execute("SELECT * FROM items")
print(con.fetchone())
# ('jeans', Decimal('20.00'), 1)
print(con.fetchone())
# ('hammer', Decimal('42.20'), 2)
print(con.fetchone()) # This closes the transaction. Any subsequent calls to .fetchone will return None
# None
连接对象的 description
属性包含符合标准的列名。
预处理语句
DuckDB 还支持使用 execute
和 executemany
方法在 API 中使用预处理语句。值可以作为附加参数传递,位于包含 ?
或 $1
(美元符号和数字)占位符的查询之后。使用 ?
符号会按照 Python 参数中传递的相同顺序添加值。使用 $
符号允许根据 Python 参数中找到的值的数量和索引在 SQL 语句中重复使用值。值会根据转换规则进行转换。
以下是一些示例。首先,使用预处理语句插入一行
con.execute("INSERT INTO items VALUES (?, ?, ?)", ["laptop", 2000, 1])
其次,使用预处理语句插入多行
con.executemany("INSERT INTO items VALUES (?, ?, ?)", [["chainsaw", 500, 10], ["iphone", 300, 2]] )
使用预处理语句查询数据库
con.execute("SELECT item FROM items WHERE value > ?", [400])
print(con.fetchall())
[('laptop',), ('chainsaw',)]
使用 $
符号进行预处理语句查询并重用值
con.execute("SELECT $1, $1, $2", ["duck", "goose"])
print(con.fetchall())
[('duck', 'duck', 'goose')]
警告 请勿使用
executemany
向 DuckDB 插入大量数据。请参阅数据摄取页面以获取更好的选项。
命名参数
除了标准的无名参数,如 $1
、$2
等,还可以提供命名参数,如 $my_parameter
。使用命名参数时,您必须在 parameters
参数中提供一个从 str
到值的字典映射。以下是一个使用示例
import duckdb
res = duckdb.execute("""
SELECT
$my_param,
$other_param,
$also_param
""",
{
"my_param": 5,
"other_param": "DuckDB",
"also_param": [42]
}
).fetchall()
print(res)
[(5, 'DuckDB', [42])]