环境与基本使用
本页目的: 把 DuckDB 装起来并跑通基本用法 —— CLI、Python API、常用 SQL、CSV 导出、 扩展机制。全部基于本机实测(DuckDB v1.5.5 Variegata,macOS arm64)。
本页是 DuckDB 实战系列第 1 篇,下一篇见 模拟数据。
1. 安装
DuckDB 有两个形态:CLI 二进制 与 Python 包。本机用 uv 管理,无需全局安装:
# Python API(临时环境,不污染项目依赖)
uv run --with duckdb python -c "import duckdb; print(duckdb.__version__)" # 1.5.5
# CLI(新版 duckdb 包不再自带 CLI,需用 duckdb-cli 包)
uvx --from duckdb-cli duckdb --version # v1.5.5 (Variegata)
⚠️ 坑:
uvx duckdb会报Package "duckdb" does not provide any executables—— 新版duckdbPython 包不再附带 CLI,要用uvx --from duckdb-cli duckdb。💡 uvx 装在哪:
uvx是临时执行,不装到当前目录,全部落在 uv 的全局缓存里 (uv cache dir查看;默认$UV_CACHE_DIR>$XDG_CACHE_HOME/uv>~/.cache/uv)。 结构大致是:wheels-v6/存下载的 wheel,archive-v0/<hash>/存解压后的包 (duckdb 的bin/duckdb就在这里),environments-v2/<hash>/是临时 venv, 用符号链接指回 archive-v0。跑完后临时 venv 清理,但包会留在缓存里复用, 所以第二次执行会快很多。想持久安装(可卸载、入口进~/.local/bin)用uv tool install duckdb-cli,那是装到~/.local/share/uv/tools/。
2. CLI 基本操作
CLI 支持 内存库(不指定文件)与 文件库(单文件持久化,就是普通文件, 可拷走/备份):
uvx --from duckdb-cli duckdb # 内存库
uvx --from duckdb-cli duckdb test.duckdb # 文件库(不存在则创建)
uvx --from duckdb-cli duckdb test.duckdb -c "SQL" # 非交互执行
交互模式常用元命令:
| 命令 | 作用 |
|---|---|
.tables | 列出表 |
.schema t | 查看建表语句 |
.mode list / .mode markdown | 切换输出格式 |
示例:
-- 文件库:建表 + 写入 + 查询
CREATE TABLE users (id INTEGER, name VARCHAR, created DATE);
INSERT INTO users VALUES (1, 'Alice', '2026-01-01'), (2, 'Bob', '2026-02-14');
SELECT id, name, strftime(created, '%Y-%m') AS ym FROM users ORDER BY id;
3. Python API
import duckdb
# 1) 连接:内存库 vs 文件库
con_mem = duckdb.connect() # 内存库
con_file = duckdb.connect("app.duckdb") # 文件库
# 2) 默认连接:不显式 connect 也能直接查
duckdb.sql("SELECT 40 + 2").fetchone() # (42,)
# 3) con.sql()(推荐,返回 relation)vs con.execute()(返回 cursor)
con_file.sql("SELECT 'a'").fetchone() # ('a',)
con_file.execute("SELECT 'b'").fetchone() # ('b',)
# 4) pandas / Arrow 互操作:直接查 DataFrame(零拷贝)
import pandas as pd
df = pd.DataFrame({"city": ["上海", "北京"], "pop": [2487, 2189]})
duckdb.sql("SELECT city FROM df WHERE pop > 2000").df() # 结果取回 DataFrame
duckdb.sql("SELECT count(*) FROM df").arrow() # 取回 Arrow RecordBatch
# 5) 结果展示
con_file.sql("SELECT ...").show() # CLI 风格的表格输出
要点: DuckDB 是进程内嵌入式数据库,没有 server、没有端口、没有序列化开销。 查询 pandas DataFrame、Arrow 表时直接读内存数据,不用导入导出。
4. 常用 SQL 特性
-- CTAS:建表并写入
CREATE TABLE sales AS
SELECT * FROM (VALUES (1,'2026-01',100),(2,'2026-01',50)) t(id, ym, amt);
-- 窗口函数
SELECT id, ym, amt, sum(amt) OVER (PARTITION BY ym) AS ym_total FROM sales;
-- DESCRIBE 查看表结构
DESCRIBE sales;
-- COPY:与文件互导(CSV / Parquet)
COPY sales TO 'sales.parquet' (FORMAT PARQUET);
COPY sales FROM 'sales.csv' (FORMAT CSV, HEADER);
-- EXPLAIN ANALYZE 查看执行计划与耗时
EXPLAIN ANALYZE SELECT ym, sum(amt) FROM sales GROUP BY ym;
5. 导出表到 CSV
最常用的是 COPY ... TO,支持分隔符、表头、压缩等选项:
-- 基本导出
COPY sales TO 'sales.csv' (FORMAT CSV, HEADER);
-- 不带表头
COPY sales TO 'sales-nohead.csv' (FORMAT CSV, HEADER false);
-- 自定义分隔符(TSV)
COPY sales TO 'sales.tsv' (FORMAT CSV, DELIMITER E'\t', HEADER);
-- 导出为 gzip 压缩的 CSV
COPY sales TO 'sales.csv.gz' (FORMAT CSV, HEADER, COMPRESSION GZIP);
-- 只导出查询结果(子查询)
COPY (SELECT id, amt FROM sales WHERE amt > 50) TO 'big.csv' (FORMAT CSV, HEADER);
实测: 1.5.5 里 COPY CSV 的
HEADER默认为 true(不写也会带表头), 需要无表头时显式写HEADER false。分隔符用DELIMITER,制表符转义写法E'\t'。
CLI 交互模式也可以用 .mode / .output 把查询结果写进文件:
导出结束后用 .output stdout 恢复终端输出(注意:.output 命令不支持行内注释)。
Python API 里 relation 自带 to_csv():
反向导入(CSV → 表)见第 4 节 COPY sales FROM ...。
6. 扩展机制
DuckDB 通过扩展提供更多功能,分两类:
| 扩展 | 安装方式 | 用途 |
|---|---|---|
parquet / json | 核心扩展,开箱即用 | Parquet / JSON 读写 |
httpfs | INSTALL httpfs; LOAD httpfs; | 读取远程 HTTP(S)/S3 文件 |
postgres_scanner | INSTALL postgres_scanner; LOAD postgres_scanner; | 连接 PostgreSQL |
INSTALL postgres_scanner; LOAD postgres_scanner; -- 需要网络下载扩展
LOAD parquet; LOAD json; -- 核心扩展直接 LOAD
-- 查看扩展状态
SELECT extension_name, installed, loaded
FROM duckdb_extensions()
WHERE extension_name IN ('parquet','json','httpfs','postgres_scanner');
坑: 1.5.5 里
LOAD httpfs会报Extension not found. Install it first—— 非核心扩展必须先INSTALL(联网下载)再LOAD;INSTALL后扩展文件缓存在~/.duckdb/extensions/。
7. 参考链接
| 资源 | 链接 |
|---|---|
| DuckDB 文档 | https://duckdb.org/docs/ |
| Python API | https://duckdb.org/docs/stable/clients/python/overview |
| 扩展列表 | https://duckdb.org/docs/stable/extensions/overview |
→ 下一站:模拟数据
Backlinks (2)
flowchart LR
n0["AI"]
n1["Database"]
n2["Dev Tools"]
n3["Emoji"]
n4["Frontend"]
n5["Game Dev"]
n6["Collection"]
n7["Languages"]
n8["Maps"]
n9["Media"]
n10["Monitor"]
n11["Study Materials"]
n12["Plans"]
n13["Storage"]
n14["对象存储基本用法(Bucket / Object / 常用操作)"]
n15["挂载 Bucket 为本地文件系统(FUSE Mount)"]
n16["对象存储签名 URL(Signed URL)原理与实战"]
n17["对象存储供应商对比(S3 / R2 / OSS / Supabase / MinIO)"]
n18["Prototypes"]
n19["Research"]
n20["Better Auth 源码阅读指南"]
n21["DuckDB 环境与基本使用"]
n22["DuckDB 实战研究"]
n23["DuckDB 模拟数据"]
n24["PostgreSQL 数据用 DuckDB 加速查询"]
n25["HK 角色阅读"]
n26["HK 台词阅读"]
n27["Hollow Knight 英语主题"]
n28["HK 物品阅读"]
n29["HK 地点阅读"]
n30["HK 世界观 / Lore 阅读"]
n31["英语学习 Dashboard"]
n32["English Scraps Archive"]
n33["English Scraps 使用指南"]
n34["Jellyfin 源码阅读指南"]
n35["Lux 资料整理"]
n36["Nest Commander 学习资料"]
n37["NestJS 源码阅读指南"]
n38["Protomaps 自建底图研究"]
n39["自制 PMTiles 地图(最简单例子)"]
n40["MapLibre 集成 Protomaps"]
n41["PMTiles 格式与工具链"]
n42["上海地区底图项目"]
n43["Redash 源码阅读指南"]
n44["Rust 学习计划"]
n45["shadcn/ui 进阶使用"]
n46["shadcn/ui 组件添加与基本使用"]
n47["shadcn/ui 实用研究(从环境到基本使用)"]
n48["shadcn/ui 环境与初始化"]
n49["TRIP 项目核心原理与代码阅读指南"]
n1 --> n22
n1 --> n24
n4 --> n47
n6 --> n0
n6 --> n1
n6 --> n2
n6 --> n3
n6 --> n4
n6 --> n5
n6 --> n7
n6 --> n8
n6 --> n9
n6 --> n10
n6 --> n11
n6 --> n12
n6 --> n13
n6 --> n19
n14 --> n16
n14 --> n17
n14 --> n18
n15 --> n14
n15 --> n16
n15 --> n17
n16 --> n18
n17 --> n14
n17 --> n16
n17 --> n18
n18 --> n14
n18 --> n15
n18 --> n16
n18 --> n17
n18 --> n38
n19 --> n20
n19 --> n22
n19 --> n31
n19 --> n34
n19 --> n35
n19 --> n36
n19 --> n37
n19 --> n38
n19 --> n43
n19 --> n44
n19 --> n47
n19 --> n49
n21 --> n23
n22 --> n1
n22 --> n19
n22 --> n21
n22 --> n23
n22 --> n24
n23 --> n21
n23 --> n24
n24 --> n22
n24 --> n23
n27 --> n25
n27 --> n26
n27 --> n28
n27 --> n29
n27 --> n30
n27 --> n33
n31 --> n27
n31 --> n32
n31 --> n33
n33 --> n31
n33 --> n32
n38 --> n8
n38 --> n39
n38 --> n40
n38 --> n41
n38 --> n42
n39 --> n41
n40 --> n18
n40 --> n42
n41 --> n39
n41 --> n42
n42 --> n40
n42 --> n41
n45 --> n46
n46 --> n45
n46 --> n48
n47 --> n4
n47 --> n19
n47 --> n45
n47 --> n46
n47 --> n48
n48 --> n46
click n0 "../../../../collection/ai/" "AI"
click n1 "../../../../collection/database/" "Database"
click n2 "../../../../collection/dev-tools/" "Dev Tools"
click n3 "../../../../collection/emoji/" "Emoji"
click n4 "../../../../collection/frontend/" "Frontend"
click n5 "../../../../collection/game-dev/" "Game Dev"
click n6 "../../../../collection/" "Collection"
click n7 "../../../../collection/languages/" "Languages"
click n8 "../../../../collection/maps/" "Maps"
click n9 "../../../../collection/media/" "Media"
click n10 "../../../../collection/monitor/" "Monitor"
click n11 "../../../../collection/reading/" "Study Materials"
click n12 "../../../../collection/scraps/plans/" "Plans"
click n13 "../../../../collection/storage/" "Storage"
click n14 "../../../../knowledge/infrastructure/cloud/object-storage/basic-usage/" "对象存储基本用法(Bucket / Object / 常用操作)"
click n15 "../../../../knowledge/infrastructure/cloud/object-storage/mount-bucket/" "挂载 Bucket 为本地文件系统(FUSE Mount)"
click n16 "../../../../knowledge/infrastructure/cloud/object-storage/signed-url/" "对象存储签名 URL(Signed URL)原理与实战"
click n17 "../../../../knowledge/infrastructure/cloud/object-storage/vendors-comparison/" "对象存储供应商对比(S3 / R2 / OSS / Supabase / MinIO)"
click n18 "../../../../prototypes/" "Prototypes"
click n19 "../../../" "Research"
click n20 "../../better-auth/" "Better Auth 源码阅读指南"
click n21 "./" "DuckDB 环境与基本使用"
click n22 "../" "DuckDB 实战研究"
click n23 "../mock-data/" "DuckDB 模拟数据"
click n24 "../postgresql-acceleration/" "PostgreSQL 数据用 DuckDB 加速查询"
click n25 "../../english/hollow-knight/characters/" "HK 角色阅读"
click n26 "../../english/hollow-knight/dialogues/" "HK 台词阅读"
click n27 "../../english/hollow-knight/" "Hollow Knight 英语主题"
click n28 "../../english/hollow-knight/items/" "HK 物品阅读"
click n29 "../../english/hollow-knight/locations/" "HK 地点阅读"
click n30 "../../english/hollow-knight/lore/" "HK 世界观 / Lore 阅读"
click n31 "../../english/" "英语学习 Dashboard"
click n32 "../../english/scraps/archive/" "English Scraps Archive"
click n33 "../../english/scraps/" "English Scraps 使用指南"
click n34 "../../jellyfin/" "Jellyfin 源码阅读指南"
click n35 "../../lux/" "Lux 资料整理"
click n36 "../../nest-commander/" "Nest Commander 学习资料"
click n37 "../../nestjs/" "NestJS 源码阅读指南"
click n38 "../../protomaps/" "Protomaps 自建底图研究"
click n39 "../../protomaps/make-own-map/" "自制 PMTiles 地图(最简单例子)"
click n40 "../../protomaps/maplibre/" "MapLibre 集成 Protomaps"
click n41 "../../protomaps/pmtiles/" "PMTiles 格式与工具链"
click n42 "../../protomaps/shanghai-map/" "上海地区底图项目"
click n43 "../../redash/" "Redash 源码阅读指南"
click n44 "../../rust/" "Rust 学习计划"
click n45 "../../shadcn-ui/advanced/" "shadcn/ui 进阶使用"
click n46 "../../shadcn-ui/components/" "shadcn/ui 组件添加与基本使用"
click n47 "../../shadcn-ui/" "shadcn/ui 实用研究(从环境到基本使用)"
click n48 "../../shadcn-ui/setup/" "shadcn/ui 环境与初始化"
click n49 "../../trip/" "TRIP 项目核心原理与代码阅读指南"