跳转到内容

数据源

English · 文档

DuckLocal 会把文件变成视图,挂到内存中的 DuckDB 连接上;如果你打开了数据库文件,则挂到该数据库文件里。无需任何配置。

打开数据的方式

三种入口都走同一套解析规则:

  1. 命令行上的路径 —— ducklocal ./logs/ billing.parquet
  2. 标题栏中的**打开数据…**对话框,既可以手动输入路径,也可以用系统文件选择器挑选路径,并且能一次打开多个
  3. 把文件或文件夹拖到窗口的任意位置

支持的文件格式

扩展名不区分大小写。

扩展名读取方式
.csv, .tsv, .txtread_csv_auto 视图
.parquetread_parquet 视图
.json, .ndjson, .jsonlread_json_auto 视图
.xlsx, .xls, .xlsb, .ods每个工作表导入为一张表

其他内容都不是数据文件 —— 参见数据库文件

工作簿是唯一会变成(而不是视图)的格式,并且会导入所有工作表:第一个工作表以文件名主干命名,其余命名为 {主干}_{工作表名}。空工作表会被跳过。列类型根据单元格推断——整数为 BIGINT,整数与浮点混合为 DOUBLE,日期为 TIMESTAMP,其他混合或无法识别的内容为 VARCHAR;空单元格导入为 NULL

文件夹与通配符

文件夹会被递归遍历,其中的每个数据文件都会变成一个视图。遍历时有两条规则:

  • 隐藏条目(以 . 开头的名字)会被跳过,也不会进入它们的子树。
  • 不跟随符号链接。指向上层目录的链接会让遍历无法终止,而被链接到的目录通常会在它真正所在的位置被遍历。

文件按排序后的顺序挂载,因此同一个文件夹每次都会生成同一个工作区。

通配符中可以包含 *(任意一串字符)和 ?(恰好一个字符)。匹配是逐路径段、直接针对文件系统进行的,因此通配符可以跨目录:

bash
ducklocal './data/2026-0*/*.parquet'

没有转义字符。** 没有特殊含义 —— 它的行为等同于单个 *,不会递归。匹配到目录的通配符会忽略该目录;只有文件才会被挂载。这里同样会跳过隐藏条目。

未加引号的通配符会先被你的 shell 展开,DuckLocal 看到的是展开后的结果,这没有问题 —— 只有当你希望由 DuckLocal 自己做展开时才需要加引号(例如 shell 匹配不到、否则会直接报错的情况)。

一次读取多个 CSV

DuckLocal 挂载的每个文件都是独立的视图,各自有各自嗅探出的 schema,所以两个互不一致的 CSV 不会互相影响。陷阱出现在一条 SQL 同时读取多个文件时:

sql
SELECT * FROM read_csv('data/*.csv', union_by_name = true)
  • 各文件的类型嗅探可能互相矛盾。 读取函数根据样本推断列类型;某列在绝大多数文件里都是数值,却在某一个文件里混进了字符串 'NULL',整个读取就会因转换错误而失败——此时在 SELECT 里做 cast 已经太迟,因为出错的是读取本身。应把所有列按文本读入,再在 SQL 里转换:

    sql
    SELECT try_cast(amount AS DOUBLE) AS amount
    FROM read_csv('data/*.csv', union_by_name = true, all_varchar = true)

    union_by_name = true 同时还能容忍各文件列集合不一致的情况。

  • 字符串 'NULL' 不是 NULL CSV 里的字面量 'NULL'(或 'N/A''null')只是普通文本,WHERE amount IS NOT NULL 过滤不掉它。请用 NULLIF(amount, 'NULL'),或者 WHERE amount <> 'NULL'

两个修法可以合并:try_cast(NULLIF(amount, 'NULL') AS DOUBLE)

数据库文件

任何存在且不是数据文件的路径,都会被当作 DuckDB 数据库打开,而不是作为视图挂载。扩展名无关紧要:.db.duckdb 乃至 .md 路径都会被当作数据库,能否真正打开由 DuckDB 决定。

有两点值得了解:

  • 无法通过指定名字来新建数据库。 不存在的路径会被报告为找不到。请打开一个已存在的数据库文件,或者以内存模式启动。
  • 如果文件无法作为 DuckDB 打开,DuckLocal 会回退到内存模式的工作区并报告该错误,而不是启动失败。

在数据库文件已打开的情况下挂载数据文件,会把这些视图写进那个数据库文件 —— 它们会持久保存在那里,而不只是存在于本次会话中。

命名

文件对应的视图以其文件名主干命名,并被整理成合法的标识符。如果该名字在连接中已被占用,DuckLocal 会追加计数:events,然后是 events_2events_3。因此,位于不同目录、主干同名的两个文件会得到不同的视图。

重复判断依据的是路径文本本身,因此 ./a.csva.csv 会被当成两个不同的文件。

限制

  • 每次打开请求最多 256 个数据文件。 这个上限针对的是一次请求中的所有路径,而不是每个文件夹分别计数 —— 它的存在是为了避免误把整个用户主目录拖进来时,连接被占用好几分钟。触发上限时,DuckLocal 会给出提示,并挂载前 256 个文件。
  • 启动时从上次会话重新挂载的文件不受该上限约束。

管理已注册的数据源

已注册的文件出现在侧栏的本地文件分组中,每个文件都带有视图名、文件名和行数。选中某个文件会为它生成一条 SELECT 语句。

文件行上的 × 会在确认对话框之后把它移除。移除会删除视图并忘掉这条注册;底层文件不会受到任何影响。

刷新 Schema 会重新加载 catalog 和已注册的文件。

会被记住的内容

已注册文件的清单 —— 它们的路径、视图名和类型 —— 存放在 DuckLocal 自己的历史数据库中,并在下次启动时重新挂载,因此你离开时的工作区就是你回来时的工作区。数据库文件本身不会被记住:除非你指定了某个数据库,否则每次启动都从内存模式开始。

磁盘上的位置参见设置与应用数据

基于 Apache-2.0 许可开源发布。