WorkBuddy数据迁移到dsh:workbuddy-to-dsh插件实战指南 说实话最开始我压根没想过要把 WorkBuddy 里的数据搬到 dsh。WorkBuddy 用了两年多模板、任务、归档、标签关系全在里面随便动一下都感觉要出事。直到我在 dsh 社区转了一圈发现插件生态已经过了“能装不能跑”的阶段workbuddy-to-dsh 这个迁移插件也更新到了相对稳定的版本我才抱着试试看的心态在测试环境里先跑了一遍。结果比我预想的顺利从导出、字段映射到最终导入 dsh整个流程不到一个小时。今天这篇就完整记录一下 workbuddy-to-dsh 的使用过程从环境准备、插件市场配置、命令参数到常见报错排查都讲清楚希望能帮到同样在 WorkBuddy 和 dsh 之间纠结的人。1. 为什么要用 workbuddy-to-dsh迁移痛点与方案选型1.1 先搞清楚 dsh 和插件市场的关系很多刚接触 dsh 的人第一个疑问是dsh 到底是个什么东西从我的使用体验来看可以把它理解成一个“本地工具中枢”——它本身只提供最基础的命令行框架真正干活的功能全靠插件来提供。而这些插件并不是官方一个个内置的是通过插件市场分发的。市场本质上是一个插件索引源你执行dsh plugin --profile web add dshmarket这条命令就是在让 dsh 去对接一个名字叫 dshmarket 的插件仓库之后你就能通过统一的dsh plugin install命令从里面安装插件。这里有两个容易被忽略的细节第一--profile web的意思是给这个市场配置指定到一个名为 web 的 profile。dsh 的 profile 机制类似一套独立的环境配置不同 profile 可以维护不同的插件列表、不同的数据目录互不干扰。我平时工作环境用web这个 profile个人测试环境用test这样不会因为想试一个小插件就把工作环境搞乱。第二插件市场添加成功不等于插件已经装好它只是打通了索引通道后面还需要单独的安装步骤。workbuddy-to-dsh 就属于这类插件它本身不是 dsh 内置的迁移工具而是社区维护的一个转换插件。它的核心价值在于把 WorkBuddy 导出的原始数据文件读进来按照你配置的映射规则转换成 dsh 可以识别的结构再通过 dsh 的导入能力写进去。有了插件市场这层机制后续工具更新不需要你手动到处找下载链接一条命令就能完成。1.2 WorkBuddy 数据迁出的难点WorkBuddy 的数据看起来很开放有导出按钮有备份功能但真正到了迁移这一步才会发现坑很多。首先是格式问题WorkBuddy 的默认导出格式虽然包含 JSON 文件但它的 JSON 结构和 dsh 对任务的字段要求完全不同。比如 WorkBuddy 里一条任务可能是task_name开头dsh 里对应的是titleWorkBuddy 的时间戳是 ISO 字符串dsh 某些版本要求必须是标准 UTC 格式。字段对不上导出来也没法直接用。其次是附件问题。WorkBuddy 里的附件不是全部塞进一个 JSON 里的而是一个主文件加一个 assets 目录目录里图片、压缩包、文档散落着。如果只是把 JSON 复制过去导入 dsh 后会发现链接全断了图片打不开。更麻烦的是关系字段WorkBuddy 里任务和标签是多对多关系还有上级任务、归档标记、协作成员等额外信息这些在纯手工导出的时候基本都会被丢掉。最后是权限和元数据。WorkBuddy 如果多人协作过每一条记录里都会有创建人、最后修改人、修改时间等字段。dsh 虽然不一定需要全部保留但你总希望至少把创建时间、更新时间这种基础元数据带过来。人工整理几百条记录还能凑合几千条的时候人眼识别根本不现实。1.3 为什么选 workbuddy-to-dsh 而不是自己写脚本说实话我自己一开始也想过写 Python 脚本去做转换把 JSON 读进来自己映射字段自己复制附件目录听起来难度不高。但真正写起来就不会这么乐观WorkBuddy 的字段版本会变我手上的导出文件里有个字段叫workload_status脚本写死了这个名字结果下一次备份导出的字段变成了status脚本直接崩掉。还有附件路径的转义、日期格式的时区处理都要反复测试。workbuddy-to-dsh 这个插件我实际用下来最大的优势就是它已经处理好了这些“脏活”。它不需要你从头理解 dsh 的底层数据结构你只需要准备一个映射配置文件告诉它“WorkBuddy 的 A 字段对应 dsh 的 B 字段”它就能完成转换并且会顺带处理附件目录的复制。另外它还支持--dry-run参数可以先跑一遍不实际写入输出一份统计和预览结果这对迁移这种高风险操作来说非常重要。注意迁移工具再怎么方便也建议先在一个测试 profile 里完整跑一遍确认没问题之后再对正式数据动手。我在这一步跳过过结果吃了个大亏后面会详细说。2. 安装前的准备环境、版本与插件市场2.1 环境要求和前置检查表安装插件之前先检查环境。我这边正常的运行环境是 Windows 11配合 Windows Terminal 使用 PowerShell 7.4同时装了 Git for Windows 用来处理插件市场仓库的拉取。dsh 并不是只能在 Windows 上跑macOS 和 Linux 上也都有对应版本但我个人大多数迁移场景都在 Windows 上完成所以下面的操作流程会以 Windows 环境为例。下面是我整理的前置检查表检查项要求说明PowerShell 版本7.0 及以上5.1 也能跑但商店版 PowerShell 会有额外问题dsh 版本1.4.0 及以上老版本对插件市场格式兼容性差Git已安装且能正常执行插件市场拉取时依赖 git网络能正常访问插件市场地址如果拉取超时考虑切换镜像源执行策略PowerShell 当前用户可绕过限制以管理员身份运行一次即可检查执行策略可以用这条命令Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass这条命令的作用是把当前用户的执行策略改成 Bypass也就是运行脚本时不再提示权限阻止。只对当前用户生效不用动系统级策略安全性上可控。执行完以后可以确认一下Get-ExecutionPolicy -List看到 CurrentUser 那一行是 Bypass 就行了。2.2 先把 dsh 插件市场加上我安装 workbuddy-to-dsh 之前先执行的是市场添加命令dsh plugin --profile web add dshmarket这条命令执行后dsh 会把 dshmarket 市场信息写入当前 profile 的配置文件里。你可以理解成把“应用商店”的地址写进了系统设置后面安装插件时 dsh 会去这个地址拉取插件清单。执行完可以查看一下dsh plugin list --profile web这个时候你会看到市场列表里多了一个 dshmarket但插件列表可能是空的。这是正常的因为你还没有安装任何具体插件。如果添加市场的时候超时或者提示拉取失败绝大多数情况下是网络问题。dsh 社区里有人会直接换一个访问更稳定的镜像地址这个在官方文档里能找到。我不建议反复重试同一个地址可以先检查一下本机是否能正常访问目标域名不能的话直接换镜像比干等更有效。2.3 安装 workbuddy-to-dsh 插件市场配置好之后安装插件就很直接了dsh plugin install workbuddy-to-dsh执行完成后再通过插件列表确认一下dsh plugin list --profile web如果正常的话你会看到 workbuddy-to-dsh 出现在已安装插件列表里同时会有版本号。插件装完之后原来的workbuddy-to-dsh命令就可以用了。我这里有个小提醒有些版本的插件命令名可能会因为打包格式变成wb2dsh如果执行命令时报“找不到命令”先回去看一下插件首页的 README以里面的实际命令名为准。插件更新也走同一条路dsh plugin update workbuddy-to-dsh我会在迁移之前先更新一次插件毕竟数据转换工具的版本直接影响结果的正确性。另外如果你使用的是 dsh 桌面版插件安装好以后在界面里就能看到导出导入的入口不需要自己敲命令。社区里提到的“dsh 桌面版赠金”我理解指的是特定活动期间桌面版给迁移用户发放的增值使用权益如果你正好在活动期内可以关注一下桌面版用来查看迁移后的数据确实比纯命令行直观很多。3. 完整迁移实操从导出到校验3.1 第一步从 WorkBuddy 导出原始数据迁移的第一步不是在 dsh 里操作而是在 WorkBuddy 里把数据完整导出。进入 WorkBuddy 的备份设置选择导出格式尽量选 JSON附加选项里把“包含附件”勾上。如果你用的是加密备份后面 workbuddy-to-dsh 解析时会多一层解密步骤我强烈建议在迁移阶段先去掉加密等确认转换没问题之后再重新启用。导出完成后你会得到两个核心东西一个 JSON 主文件和一个 assets 附件目录。这两个东西要放在同一个文件夹下比如我这里统一放在D:\migration\workbuddy_backup下D:\migration\workbuddy_backup ├── workbuddy_backup.json └── assets ├── images ├── files └── attachments导出以后先别急着转换花两分钟抽查一下 JSON 文件里的记录数量和数据格式。可以打开 JSON 文件看一下顶层结构确认字段名是否和你预期的一致。这一步的抽查看起来麻烦但能省掉后续很多无效转换的时间。3.2 第二步准备字段映射规则workbuddy-to-dsh 转换时会读取一个映射配置文件告诉它 WorkBuddy 里的字段应该如何对应到 dsh 字段。我习惯在导出目录下新建一个mapping.yml文件内容类似下面这样mapping: task: name: title description: content created_at: created_time updated_at: updated_time tags: tags attachment: source_dir: assets target_dir: attachments这个配置的行文逻辑很直白左侧是 WorkBuddy 里的字段名右侧是 dsh 里的目标字段名。实际使用的时候字段名会根据你的数据版本有差异所以不要照抄先看一下你导出 JSON 里的真实 key。除了字段名日期格式也需要留意。WorkBuddy 里创建的日期通常是带时区的 ISO 字符串比如2024-06-01T10:20:3008:00dsh 在导入时基本能识别但如果你的系统时区设置不正常转换结果可能会差几个小时。建议在映射配置里增加一个时区的显式说明字段具体写法插件文档里有我这里就不展开了。提示映射文件建议用一个独立的配置文件保存不要直接改插件自带的默认配置。这样后面想调整字段对应关系只需要改自己这份文件不会污染插件环境。3.3 第三步执行 dry-run 预览迁移结果正式转换之前一定先跑一次 dry-run。dry-run 模式下workbuddy-to-dsh 会解析原始数据、套用映射规则、模拟转换但不会真的生成 dsh 导入文件。你可以理解成考试前的模拟卷不评分但能让你知道自己哪些知识点没掌握。命令大概是这样workbuddy-to-dsh convert --input ./workbuddy_backup.json --mapping mapping.yml --output ./out --dry-run执行完以后终端会输出一份统计信息包括识别到的任务数量、附件数量、映射失败的字段数量。我那次跑 dry-run 就发现问题了——WorkBuddy 里有个自定义字段priority_level没有在映射配置里出现统计结果里直接标成了 unmapped。如果不是这步后面导入 dsh 之后这个字段就会静默丢失等发现的时候再去补就麻烦很多。dry-run 输出确认没有问题之后再把--dry-run参数去掉执行正式转换。3.4 第四步正式转换并导入 dsh去掉 dry-run 参数的正式转换命令workbuddy-to-dsh convert --input ./workbuddy_backup.json --mapping mapping.yml --output ./out转换完成后./out目录下会出现 dsh 可以识别的数据文件和相关附件目录。此时不要急着自己去翻文件直接使用 dsh 的导入命令dsh import ./out/如果你希望增量导入而不是整体覆盖或者你之前已经导入过部分内容建议加上合并参数dsh import ./out/ --merge--merge的作用是导入时如果字段 ID 和现有数据重合会合并更新而不是新建重复条目。我第一次迁移时没加这个参数结果一条数据被导入了两遍后续查重麻烦得要死。导入完成后用以下两个命令做快速校验dsh stats dsh search migrated --limit 10dsh stats会显示当前数据量统计可以和 WorkBuddy 里原本的记录数做个简单对比。dsh search是用来抽查内容的我习惯给每条导入数据打一个migrated标签这样搜索起来特别快。除了总数对比还要随机挑几条任务看看标题、内容和附件有没有丢失。附件检查最容易忽略也是最容易出问题的环节。随便点开几张图片和文档确认链接有效。我在第一次迁移时就是跳过了这一步结果导入后才发现上百个附件链接全断了只好回滚重新转教训极其深刻。4. 常见报错排查把坑提前帮你踩掉4.1 商店版 PowerShell 执行 dsh 报错怎么定位这个坑是我在 Windows 上遇到的最典型问题也是很多人问得最多的一个。如果你是从 Microsoft Store 安装的 PowerShell打开之后执行dsh命令可能会遇到两类报错。一类是提示“dsh 不是内部或外部命令”另一类是执行插件脚本时被安全策略拦截。前者通常不是 dsh 没装好而是商店版 PowerShell 在沙箱环境里没有继承系统级的 PATH 环境变量。微软商店版 PowerShell 走的是 MSIX 打包方式它运行在 AppContainer 沙箱中对系统路径的访问和传统命令行终端不完全一致。你明明已经在系统环境变量里配置了 dsh 的路径但在商店版终端里执行Get-Command dsh就是找不到。解决办法我推荐两个方向第一尽量不用商店版 PowerShell 来跑 dsh 命令。直接用 Windows Terminal 里的 PowerShell 7 或者传统 PowerShell 5.1这两个终端对系统路径的读取是正常的。第二如果你因为某些原因只能用商店版那就在执行 dsh 命令之前手动指定完整路径$dshPath C:\Program Files\dsh\dsh.exe $dshPath plugin list把$dshPath替换成你本机实际的 dsh 安装路径就行。老实说这个方案只适合应急日常操作还是建议切换到 Windows Terminal 环境。如果你遇到的是执行策略拦截执行下面这条命令即可Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass然后重新打开终端确认Get-ExecutionPolicy -Scope CurrentUser返回 Bypass。这个问题本质上不是 dsh 的锅是 PowerShell 默认的安全策略太严格对任何第三方脚本都先拦一手。4.2 dsh 命令“找不到”的隐蔽原因除了商店版 PowerShell还有一种“找不到命令”的情况非常隐蔽。你明明在系统里装好了 dsh之前在终端里也能正常执行突然某一天打开新的 PowerShell 窗口执行dsh却提示找不到命令。我在自己的电脑上就遇到过排查了半天才发现是环境变量 PATH 里 dsh 的安装路径被某个软件的安装程序悄悄移除了。这种时候不要急着重装 dsh先用下面这条命令检查一下命令的实际位置Get-Command dsh -All如果返回结果里能看到 dsh 的路径说明命令本身存在只是当前终端的 PATH 没有包含它。那就手动把 dsh 所在的目录追加到 PATH 里$env:Path ;C:\Program Files\dsh当然这个修改只在当前终端会话中生效。如果想永久生效需要去系统环境变量设置里手动加或者在 PowerShell profile 文件里配置。我不建议随便把一堆路径塞进系统级 PATH容易造成环境混乱优先考虑在用户级 PATH 里添加。如果执行Get-Command dsh -All也找不到再考虑是不是安装目录被安全软件清理了。我见过某些安全软件把命令行工具当成可疑程序处理如果你也遇到类似情况检查一下隔离区总没错。4.3 插件市场添加成功但拉不到插件插件市场添加成功了执行dsh plugin list --profile web能看到市场但dsh plugin install workbuddy-to-dsh时提示找不到这个插件这个问题也经常有人问。一般有两种情况。第一种是 profile 用错了。你添加市场时用的是--profile web安装时如果漏掉了--profile参数dsh 会默认操作当前激活的 profile可能就不是 web。那么它在 web 这个市场里搜不到插件就很正常了。解决方法是安装时也带上参数dsh plugin --profile web install workbuddy-to-dsh第二种是插件市场索引缓存损坏。dsh 拉取市场插件清单后会在本地缓存一份如果缓存文件损坏或版本过旧即使市场本身已经更新它也搜不到新插件。这种情况可以把缓存目录清掉再重试。缓存目录一般在用户主目录下的.dsh文件夹里执行下面的命令前先确认路径dsh cache clear清缓存不会影响已安装的插件只是强制 dsh 重新拉取一次市场索引操作成本很低。4.4 归档插件、破甲插件和迁移插件一起用容易冲突dsh 社区里经常看到“破甲插件”这个叫法很多新用户以为是什么特殊工具其实不是。它只是一个兼容层插件专门用来处理旧版本导出包的格式问题类似一个翻译官让新版本 dsh 能识别老工具的导出数据。听起来和 workbuddy-to-dsh 有点像但它们解决的问题不一样workbuddy-to-dsh 负责把 WorkBuddy 数据转换成 dsh 结构破甲插件负责的是已存在于 dsh 生态内的旧格式文件。这两类插件如果同时启用迁移时可能会发生冲突。我在一次迁移中同时启用了归档管理插件和破甲插件执行导入时系统提示文件占用原因是归档插件会自动对导入目录做一次归档快照而破甲插件也在尝试读取同样的文件。两个工具都认为自己应该接管这个目录结果互相卡住。解决办法有两个。一个是给插件设置执行优先级dsh plugin priority workbuddy-to-dsh 50把 workbuddy-to-dsh 的优先级调成 50确保它优先处理导入目录其他插件不抢。另一个方法更干脆迁移期间暂时禁用归档插件dsh plugin disable dsh-archive等导入完成、数据校验没问题再恢复启用。我在正式迁移时用的就是第二种方法简单直接减少了很多不确定性。4.5 大文件迁移时的内存溢出WorkBuddy 数据量大到一定程度比如上万条任务加好几个 GB 的附件转换时可能会报内存溢出或者直接卡死。workbuddy-to-dsh 在解析整个 JSON 的时候会把一部分数据结构加载到内存里数据量越大内存占用越高。我的建议是先分批处理利用命令自带的 limit 和 offset 参数回到第一次转换的思路。假设你导出目录里数据有 10000 条不要一次性转换先转前 5000 条workbuddy-to-dsh convert --input ./workbuddy_backup.json --mapping mapping.yml --output ./out_part1 --limit 5000 --offset 0再转剩下的部分workbuddy-to-dsh convert --input ./workbuddy_backup.json --mapping mapping.yml --output ./out_part2 --limit 5000 --offset 5000这样每个 batch 的数据量小处理起来不会把内存吃满。分批导入 dsh 的时候记得用--merge避免重复创建。如果是几十 GB 级别的附件我建议把附件复制单独放在存储盘的 SSD 区域机械硬盘上文件太多会明显拖慢读取速度。5. 使用技巧与扩展建议5.1 用 profile 区分工作区和测试区整个迁移过程中对 dsh 最有好感的设计就是 profile 机制。它让“测试环境”和“生产环境”之间隔了一道明确的墙。我的做法是创建两个 profile一个叫web一个叫test。web里放正式数据保持稳定test里随便折腾装什么插件都不怕。工作流是这样的先在 test profile 里把 workbuddy-to-dsh 的转换和导入完整跑一遍确认没有字段丢失、没有附件断链再用同一套命令在 web profile 里正式导入。当时我为了试插件在 test profile 里反复导出导入至少五次正式 profile 里却一次污染都没发生过。如果你打算长期维护 dsh 数据建议从一开始就做好 profile 规划别把所有环境都揉在一个 profile 里。5.2 把日常迁移写成脚本迁移操作来回就那么几条命令但命令多了容易漏。我在第一次测试迁移时就是因为少敲了一个--mapping参数导致转换出来的数据全部走了默认映射字段对不上。后面我直接把整个流程写成一个脚本每次迁移跑一下省心很多。下面是我用的一个简化版 bash 脚本#!/bin/bash set -e BACKUP_JSON./workbuddy_backup.json MAPPING./mapping.yml OUTPUT_DIR./out echo step 1: dry-run 预览 workbuddy-to-dsh convert --input $BACKUP_JSON --mapping $MAPPING --output $OUTPUT_DIR --dry-run read -p dry-run 结果确认无误输入 y 继续: confirm if [ $confirm ! y ]; then echo 退出迁移 exit 1 fi echo step 2: 正式转换 workbuddy-to-dsh convert --input $BACKUP_JSON --mapping $MAPPING --output $OUTPUT_DIR echo step 3: 导入 dsh dsh import $OUTPUT_DIR --merge echo step 4: 校验 dsh stats脚本里特意保留了交互确认的环节等 dry-run 结果确认之后才进入正式转换。手动操作的时候很容易忽略这个步骤脚本强制你停下来看一眼结果这个习惯能帮你躲掉很多低级错误。5.3 迁移后的数据维护与备份导入完成只是开始后面数据维护才是日常大头。我之前遇到一个尴尬的情况迁移之后 dsh 里的数据和 WorkBuddy 里还同时在更新两边就像两个同时前进的火车随时可能对不上。后来我给自己定了个规矩切到 dsh 作为主力工具之后WorkBuddy 那边当天就停止新增数据只保留查询便宜。不然双写双维护反而比不迁移还累。dsh 自身的备份我用的是归档管理插件。归档插件的好处是可以给数据做定期快照不需要手动把整个数据目录复制出来。执行归档创建命令插件会自动读取当前数据状态并生成一份归档记录后续如果需要回滚到某个时间点直接调用归档恢复就行。这个策略在我后面跳版本升级的时候帮了大忙至少两次误删数据都是靠归档记录找回来的。数据归档的频率我建议至少一周一次如果你每天都在大量录入内容可以加密归档频率。别等到出了事才想起来备份那真的很被动。5.4 迁移时容易忽略的小细节整个流程跑下来有几个小细节值得单独提一下。第一原始导出文件千万别删至少保留到 dsh 正式运行一周以后。你在 dsh 里发现问题需要回看原始数据时这个文件就是唯一的依据。第二附件目录里的文件名不要手动改动workbuddy-to-dsh 转换时会根据原始文件路径生成关联关系你一旦改了文件名链接就会断。第三导入 dsh 之后建议先在桌面版里把关键记录打开看一眼。桌面版和命令行版的底层数据一致但界面展示上偶尔会有明确的字段不显示的问题桌面版更容易发现这种展示层问题。我还想特别强调一下“桌面版赠金”这件事。它不是虚拟的承诺而是实际能立刻用上的体验。dsh 桌面版有两个功能我离不开一个是可以直接浏览迁移后的任务时间线另一个是可以在地图视图里看带地理标签的归档记录。命令行里看数据只能看文本桌面版能看到附件和地图这种直观对比能加快你对“迁移成功”这件事的信心。迁移之后并行运行期间如果两边数据出现差异不要手动去 dsh 里后台改数据记录下差异项统一时间处理。我在第一个星期里就发现了两条标签映射错误都是在 dsh 里直接改了结果后来重新导入 merge 时又把旧标签带回来了折腾不少。正确做法是修正映射配置重新跑一次增量导入。最后再多说一句workbuddy-to-dsh 并不是万能的它在字段复杂到一定程度时仍需人工介入比如 WorkBuddy 里的自定义脚本字段、复杂的动态表单结构这些如果和 dsh 的目标结构差异太大映射配置就会变得很长。但绝大部分普通任务、标签、附件、时间字段的迁移它都能做得比较干净。如果你也准备从 WorkBuddy 迁移到 dsh我的建议很直接先在 test profile 里跑一次完整的 dry-run确认统计结果和字段映射没有遗漏之后再碰正式数据。别跳过这步省下来的那几分钟很可能在后面的排查环节加倍还回去。