DuckDB Python 软件包拥有独立的仓库 duckdb/duckdb-python,并使用 pybind11 创建 DuckDB 的 Python 绑定。
先决条件
本指南假设:
- 您拥有一个可运行的 DuckDB Python 软件包源码副本(包含 git 子模块和标签)。
- 您已安装 Astral UV 0.8.0 或更高版本。
- 您在
duckdb-python源码的根目录下运行命令。
我们建议使用 Astral UV 进行 Python 环境和依赖管理。虽然可以使用 pip 通过无隔离的编辑模式安装(editable install)来搭建开发环境,但本指南不提供相关操作说明。
我们使用 CLion 作为 IDE。本指南不包含其他 IDE 的具体说明,但设置过程应当类似。
1. DuckDB Python 仓库
首先将 duckdb-python fork 到个人仓库,然后克隆您的 fork 版本。
git clone --recurse-submodules YOUR_FORK_URL
cd duckdb-python
git remote add upstream https://github.com/duckdb/duckdb-python.git
git fetch --all
如果您之前在克隆时未包含子模块:
git submodule update --init --recursive
git remote add upstream https://github.com/duckdb/duckdb-python.git
git fetch --all
重要注意事项
- DuckDB 作为 git 子模块分发,必须进行初始化。
- DuckDB 版本判定依赖于本地 git 标签的可用性。
- 如果在具有不同子模块引用的分支之间切换,请添加 git 钩子。
git config --local core.hooksPath .githooks/
2. 安装 Astral uv
安装 uv 0.8.0 或更高版本。
开发环境设置
1. 平台特定设置
所有平台
- 支持 Python 3.9+
- 要求 uv >= 0.8.0
- CMake 和 Ninja(通过 UV 安装)
- C++ 编译器工具链
Linux (Ubuntu 24.04)
sudo apt-get update
sudo apt-get install ccache
macOS
# Xcode command line tools
xcode-select --install
Windows
- Visual Studio 2019+(需支持 C++)
- Git for Windows
2. 安装依赖并构建
分两步设置开发环境:
# Install all development dependencies without building the project
uv sync --no-install-project
# Build and install the project without build isolation
uv sync --no-build-isolation
为什么要分两步?
uv sync默认使用 scikit-build-core 通过持久化构建目录进行编辑模式安装。- 构建过程发生在隔离的临时环境中,此时 cmake 的路径指向不存在的目录。
- 先安装依赖,再进行非隔离构建,可以确保正确的 cmake 集成。
3. 启用 Pre-Commit 钩子
我们在 CI 中运行多项 linting、格式化和类型检查。您可以手动运行所有这些检查,但为了方便起见,您可以安装与 CI 中完全一致的 git 钩子(通过 pre-commit),该工具已包含在开发依赖中。
uvx pre-commit install
这会在提交通过前运行所有必要的检查。
您还可以安装 post-checkout 钩子,它会自动运行 git submodule update --init --recursive。当您在 main 分支和 bugfix 分支之间切换时,这可以确保 duckdb 子模块始终正确初始化。
uvx pre-commit install --hook-type post-checkout
4. 验证安装
uv run python -c "import duckdb; print(duckdb.sql('SELECT 42').fetchall())"
开发工作流
运行测试
运行所有测试
uv run --no-build-isolation pytest ./tests --verbose
仅运行快速测试(排除 slow 目录)
uv run --no-build-isolation pytest ./tests --verbose --ignore=./tests/slow
测试覆盖率
带覆盖率运行(使用 --coverage 编译扩展以获取 C++ 覆盖率)
COVERAGE=1 uv run --no-build-isolation coverage run -m pytest ./tests --verbose
检查 Python 覆盖率
uv run coverage html -d htmlcov-python
uv run coverage report --format=markdown
检查 C++ 覆盖率
uv run gcovr \
--gcov-ignore-errors all \
--root "$PWD" \
--filter "${PWD}/src/duckdb_py" \
--exclude '.*/\.cache/.*' \
--gcov-exclude '.*/\.cache/.*' \
--gcov-exclude '.*/external/.*' \
--gcov-exclude '.*/site-packages/.*' \
--exclude-unreachable-branches \
--exclude-throw-branches \
--html --html-details -o coverage-cpp.html \
build/coverage/src/duckdb_py \
--print-summary
构建 Wheel 包
为您的系统构建 wheel
uv build
为特定 Python 版本构建
uv build -p 3.9
清理构建产物
uv cache clean
rm -rf build .venv uv.lock
IDE 设置 (CLion)
对于 CLion 用户,可以配置项目以进行 Python 扩展的 C++ 调试。
CMake 配置
在 Settings → Build, Execution, Deployment → CMake 中,创建一个 Debug 配置文件:
- 名称: Debug
- 构建类型: Debug
- 生成器: Ninja
- CMake 选项
-DCMAKE_PREFIX_PATH=$CMakeProjectDir$/.venv;$CMAKE_PREFIX_PATH
Python 调试配置
创建一个 CMake Application 运行配置:
- 名称: Python Debug
- 目标:
All targets - 可执行文件:
PROJECT_DIR/.venv/bin/python3 - 程序参数:
$FilePath$ - 工作目录:
$ProjectFileDir$
这允许设置 C++ 断点并调试使用 DuckDB 扩展的 Python 脚本。
调试
命令行调试
设置断点并使用 lldb 进行调试
# Example Python script (test.py)
# import duckdb
# print(duckdb.sql("select * from range(1000)").df())
lldb -- .venv/bin/python3 test.py
在 lldb 中
# Set breakpoint (library loads when imported)
(lldb) br s -n duckdb::DuckDBPyRelation::FetchDF
(lldb) r
跨平台测试
您可以手动在自己的 fork 上针对任意分支运行打包工作流,通过 GitHub Actions web 界面选择平台和测试套件。
故障排除
构建问题
缺少 git 标签: 如果您 fork 了 DuckDB Python,请确保您拥有上游的标签。
git remote add upstream https://github.com/duckdb/duckdb-python.git
git fetch --tags upstream
git push --tags
平台特定问题
Windows 编译: 确保安装了带有 C++ 支持的 Visual Studio 2019+。