# 常见问题排查

> DuckLocal 常见问题的解决办法：找不到 ducklocal 命令、文件挂载失败、数据库打不开、附加数据库、访达与快速查看、查询卡住、S3 凭据与仪表盘问题。

Source: https://ducklocal.app/docs/zh/troubleshooting

**[English](../troubleshooting.md)**

先确认具体现象，排查对应原因，并按步骤修复。如果文中未列出你遇到的问题，请[提交 issue](https://github.com/JetSquirrel/DuckLocal/issues)，并说明具体操作步骤与实际表现。

## 安装与启动

| 症状 | 原因与解决 |
| --- | --- |
| 在 Intel Mac 上打不开 | macOS 发布版只为 Apple silicon 构建。在 Intel 上请[从源码构建](development.md#build-and-run) |
| 文档里的快捷键在 Windows 或 Linux 上没反应 | 把 **⌘** 换成 **Ctrl**：⌘↵ 在那里是 Ctrl+Enter |
| `ducklocal: command not found` | 磁盘映像只安装应用，不安装命令。[把可执行文件链接到 PATH](getting-started.md#add-command)即可 |
| 窗口开着时终端被占用 | 从终端打开 GUI 会在前台运行。改从“应用程序”启动，或者就把那个终端留给它 |
| 历史、设置或已登记的文件不再保存 | 另一个 DuckLocal 正在运行，占用了应用数据文件。退出另一个后重新启动 |
| **DuckLocal 上次意外退出** | 它崩溃了，并在日志文件夹里留了一份报告。点 **显示报告**，附在 [issue](https://github.com/JetSquirrel/DuckLocal/issues) 里，见[存储位置](settings-and-data.md#where-things-are-stored) |
| **检查更新失败** | 鼠标悬停看原因：没联网、代理拦截，或下载的文件和校验值不符。点击重试，或者去 GitHub 下载，见[检查更新](settings-and-data.md#update-check) |

## 打开数据

| 症状 | 原因与解决 |
| --- | --- |
| 指定的路径报 `文件不存在` | 路径不存在，或者相对路径的起点和你以为的不一样。用绝对路径最稳妥 |
| 文件夹报告没有数据文件 | 里面没有匹配 `.csv`、`.tsv`、`.txt`、`.parquet`、`.json`、`.ndjson`、`.jsonl`、`.xlsx`、`.xls`、`.xlsb` 或 `.ods` 的文件 |
| 文件夹导入的文件比预期少 | 隐藏条目和符号链接会跳过，一次最多挂载 256 个文件。把子文件夹分开来打开 |
| 某个路径意外地作为数据库打开了 | 只要文件存在但不是数据文件，就会当作 DuckDB 数据库打开。打不开时，DuckLocal 会说明原因；如果是在启动时，会退回内存模式。见[打开数据库](#opening-a-database) |
| **未挂载 …：当前数据库已有名为 … 的表或视图** | 当前数据库里有一个与已登记文件同名的表或视图。DuckLocal 不会替换它。把其中一个改名或删除，或者从 **本地文件** 移除该文件后重新打开，让它拿到新名字 |
| **无法恢复相对路径 …** | 这个文件是按相对路径登记的，新会话里无法解析。从 **本地文件** 移除后重新打开 |
| 视图名是 `sales_2` 而不是 `sales` | 已有同名的文件或表，新的那个就加了后缀 |
| 文件对应的视图不是最新的 | 视图每次查询都会读取文件。如果 CSV 的列结构变了，点侧栏的 **刷新 Schema** |

## 打开数据库 {#opening-a-database}

| 症状 | 原因与解决 |
| --- | --- |
| 提示说数据库由更新版本的 DuckDB 创建 | 文件的存储格式比 DuckLocal 内置的 DuckDB 能读的更新。在创建该文件的那个 DuckDB 里运行提示中给出的 `ATTACH … COPY FROM DATABASE` 几行，再打开复制出来的文件。见[数据库文件打不开时](data-sources.md#when-a-database-will-not-open) |
| 提示说数据库来自 DuckDB v0.9 或更早版本 | 用原来的 DuckDB 执行 `EXPORT DATABASE 'dir'`，再在 DuckLocal 里执行 `IMPORT DATABASE 'dir'` |
| 提示说这是 SQLite 数据库 | 不要直接打开，改用 **打开 → 附加数据库…** 把它附加进来 |
| 提示说这个文件不是 DuckDB 数据库文件 | 它的扩展名不在 DuckLocal 认作数据文件的范围内，于是被当作数据库尝试打开。把扩展名改成[支持的格式](data-sources.md#支持的文件格式)，或者在 SQL 里读取，例如 `SELECT * FROM read_csv('export.dat')` |
| DuckDB 报告无法给文件加锁（could not set lock） | 另一个程序——另一个 DuckDB、某个脚本、另一个应用——正以可写方式打开这个数据库，而 DuckDB 只允许一个进程写同一个文件。在那边关掉它，再重新打开 |
| DuckDB 报告权限不足（permission denied） | 你的账户读不了这个文件，或者写不了它：主数据库是以可写方式打开的。修改文件权限，或者勾选 **只读** 把它附加进来 |
| 打开数据库失败，什么都没变 | DuckLocal 运行期间这是正常的：打开失败时保留原来的工作区。看通知里的原因 |
| 状态栏提示 **DuckDB v1.x+ 可读**，同事却打不开这个文件 | 对方的 DuckDB 比这个版本旧。对方需要升级，或者由你用较旧的 `STORAGE_VERSION` 复制一份，见[哪些 DuckDB 能读这个数据库](data-sources.md#storage-version) |

## 附加数据库

| 症状 | 原因与解决 |
| --- | --- |
| 重新启动后，附加的数据库不见了 | 启动时它的文件不在记录的路径上，所以被跳过。登记仍然保留；把文件放回去，下次建立连接时它就会回来 |
| **这个数据库已经打开了，名为 …。** | 这个文件已经是主数据库，或者已经以这个名字附加。直接用这个名字查询即可 |
| **无法附加 …：名称 … 已被当前数据库占用。** | 连接里已经有别的东西用了记录的别名——比如你在 SQL 里用同样的名字附加过一个数据库。先 `DETACH` 那一个，再重新打开数据库或重启应用 |
| 写入附加的数据库失败 | 它是以只读方式附加的（默认如此）。在侧栏选 **分离数据库**，再取消勾选 **只读** 重新附加 |
| 附加时新建了一个空数据库 | 取消勾选 **只读** 时，不存在的 DuckDB 路径会被新建。分离它，删掉这个空文件，再检查路径 |
| 不带库名的表名找到了别的表 | 不带库名的表名在默认数据库里查找。右键点击数据库选 **设为默认数据库**，或者写成 `别名.表` |

## 访达与快速查看

以下内容只适用于 macOS。

| 症状 | 原因与解决 |
| --- | --- |
| 双击 `.parquet` 或 `.duckdb` 文件打开了别的应用 | 那个应用已经是默认应用。在访达里 **显示简介 → 打开方式**，选 DuckLocal，再点 **全部更改…** |
| 双击 CSV 或 Excel 文件没有用 DuckLocal 打开 | 有意如此：DuckLocal 不抢这些格式。用 **打开方式 → DuckLocal**，或者把文件拖到程序坞图标上 |
| **打开方式** 里没有 DuckLocal，或按空格键看不到 DuckLocal 的预览 | macOS 还没登记这个应用。把它移到“应用程序”里并启动一次。预览的话，再在终端里运行 `qlmanage -r`，并在“系统设置”的扩展设置里确认快速查看下的 **DuckLocal Preview** 已开启 |
| 普通 `.json` 或 Excel 文件没有 DuckLocal 的预览 | 有意如此：这些交给 macOS 自带的预览。`.jsonl` 和 `.ndjson` 文件会有预览 |
| 预览只显示 50 行 | 有意如此：预览从不扫描整个文件。其余的数据请在 DuckLocal 里打开查看 |
| `.duckdb` 文件的预览显示错误 | 预览用的是 DuckLocal 自带的 DuckDB，所以较新 DuckDB 写的文件在这里同样打不开。见[打开数据库](#opening-a-database) |

## 运行查询

| 症状 | 原因与解决 |
| --- | --- |
| **运行** 没反应 | 已有查询在运行。点运行旁边的 **停止**，或按 **⌘.**，即可中断 |
| 查询失败，报 `Interrupted` | 运行期间有人点了 **停止**（或按了 ⌘.）。重新运行即可 |
| SQL 里有一段红色波浪线 | 上次运行在那里出错。看 *查询失败* 提示里的信息；下次运行时标记会清除 |
| **⌘↵** 显示了编辑器而不是运行 | 在首次运行界面上，⌘↵ 的意思是“给我一个编辑器”。再按一次就会运行 |
| 结果提前截断并有提示 | 达到了 100,000 行或 2,000,000 个单元格的上限。缩小查询范围即可，没有分页 |
| 时间戳看起来偏了 | 表格里的时间戳是 UTC，不是本地时间 |
| `TIMETZ` 的时区偏移不见了，或者 `BIT`、`BIGNUM` 的值看起来是一串字节 | 这些类型在传给 DuckLocal 的途中无法和普通值区分。在 SQL 里写 `CAST(column AS VARCHAR)` 就能看到真实的值 |
| 排序没有带回预览之外的行 | 点表头只会重排已加载的行。要在截断之前对完整结果排序，请在 SQL 中使用 `ORDER BY` |
| 查询需要尚未安装的扩展 | 不再自动下载缺失的扩展。先在 **扩展** 标签页显式安装，再加载或重跑查询 |
| 0.3.0 之前能运行的查询，提示扩展未安装或函数不存在 | DuckLocal 0.3.0 用的是 DuckDB 2.0，装好的扩展按 DuckDB 版本分开存放。在 **扩展** 标签页里重新安装即可，见[扩展](schema-and-history.md#extensions) |
| `minutes` 这样的裸列别名导致解析错误 | 它是 SQL 关键字。写成 `AS minutes`，或者给别名加双引号：`SELECT count(*) AS "minutes" FROM events` |
| 点了表或历史记录后我的 SQL 没了 | 这类点击会替换编辑器里的全部内容。临时试写的 SQL 最好放在新的查询标签页里 |
| 导出时悄悄覆盖了文件 | 导出会直接写入给定的路径，不作询问。换个文件名即可 |

## S3

| 症状 | 原因与解决 |
| --- | --- |
| S3 凭据丢了 | 凭据本来就只在当前会话有效，打开或切换数据库也会清除。重新配置即可 |
| 离线时配置 S3 失败 | 首次使用会执行 `INSTALL httpfs`，要下载扩展。联网装过一次后就会缓存下来 |
| 临时（STS）凭据被拒绝 | 不会发送会话令牌（session token），请改用长期密钥，见 [S3 与 httpfs](s3.md#limitations) |
| bucket 看起来比实际少 | 每一层最多列出 1,000 个条目。改用通配符查询，比如 `'s3://bucket/prefix/*.parquet'` |

## 仪表盘（dashboard）

| 症状 | 原因与解决 |
| --- | --- |
| 仪表盘的图表提示查询必须只读 | `.dash` 里的查询试图写入（DDL、DML、`COPY`、`ATTACH` 等）。仪表盘只执行只读语句；准备工作请放到 SQL 编辑器里做 |
| agent 没看到我的评论 | 评论不会自动发给谁，要 agent 自己去读。让它运行 `ducklocal comments 文件`；装了[官方 skill](cli.md#安装官方-skill) 的 agent，直接说“处理 文件 上的评论”即可 |
| agent 的回复或修改没有显示 | 窗口在一秒内就会跟上规格文件和 `文件.comments.json` 的变化。如果规格文件已经通不过校验，仪表盘会保留上一个能用的版本，并在上方说明原因；点 **查看 spec** 看文件内容 |
| 仪表盘里的 `PIVOT` 被拒绝 | 嵌在 `SELECT` 或 `WITH` 里的 `PIVOT` 必须写明取值。请列出取值：`PIVOT t ON channel IN ('Web', 'Store') USING sum(revenue)`，或者让查询以 `PIVOT` 开头 |

## 外观

| 症状 | 原因与解决 |
| --- | --- |
| 每次启动主题都回到浅色 | 主题不会在两次启动之间保存，语言会保存 |
| 文字或图标太小 / 太大 | 用标题栏的 **Aa** 按钮，或 ⌘+ / ⌘− / ⌘0。见[界面大小](settings-and-data.md#interface-size) |
| 界面语言不对 | 用标题栏的 `EN` / `中` 按钮切换，选择会记住 |

## 从头开始

要清除历史、已登记的文件、打开的标签页和设置，先退出 DuckLocal，再删除它的应用数据目录：

```bash
rm -rf ~/Library/Application\ Support/DuckLocal
```

数据文件本身不受影响，删掉的只是 DuckLocal 自己的记录。这个目录里具体存了什么，见[设置与应用数据](settings-and-data.md)。
