mcpField
D
datalad

datalad

github.com/kalarislabs数据与数据库7344 次安装4 天前更新
代码仓库

关于 datalad

DataLad 是构建在 Git 和 git-annex 之上的数据管理层,适用于包含大型文件、分布式存储或嵌套数据集的项目。它面向需要按需获取数据,并以机器可读记录保存分析命令以便重跑的研究团队。

主要功能

  1. 01使用 Git 跟踪数据集历史和结构
  2. 02通过 git-annex 管理大型文件内容
  3. 03按需获取文件或子目录
  4. 04用 datalad run 记录命令输入和输出
  5. 05用 datalad rerun 重放已记录命令
  6. 06组织具有独立历史的嵌套数据集

适用场景

  1. 01处理大型数据集而无需下载全部内容
  2. 02仅获取分析所需的文件
  3. 03记录并重跑数据处理命令
  4. 04同时发布数据集历史和 annex 文件内容

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/kalarislabs/research-agent-skills --skill datalad

安装后在 Claude Code 中输入/datalad确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
data-access.md
provenance.md
publishing.md

详细介绍

DataLad

概述

DataLad 是构建在 Git 和 git-annex 之上的数据管理层。Git 跟踪数据集结构、小型文本文件和历史记录。git-annex 跟踪大型文件的内容,将每个文件存储为一个键,并将字节保存在本地仓库之外的某个位置。

这是最重要的一点,因为它意味着刚克隆的数据集包含完整的历史记录和完整的文件列表,却几乎不包含任何数据。克隆一个 100 TB 的数据集只需几秒钟,占用几 MB 空间。只有在需要时,才会通过 datalad get 按文件获取字节内容。

DataLad 增加的第二项功能是来源追踪。datalad run 会执行命令,并将结果与机器可读的记录一同提交,其中记录了命令、输入和输出。datalad rerun 会读取该记录并重新执行。这让“这个图表是如何生成的”从考古问题变成了一条命令。

何时使用 DataLad,而不是普通 Git

在以下任一情况下使用 DataLad:

  • 文件太大,Git 难以轻松处理,或者数据总量超过了每位协作者愿意存储在磁盘上的容量。
  • 数据存放在多个位置(实验室服务器、集群临时存储、S3、超级计算机),而你需要知道哪些位置有副本。
  • 分析必须能够重新执行,普通提交消息不足以作为证据。
  • 你使用来自 OpenNeuro、DANDI 或 datasets.datalad.org 的已发布数据集,这些数据集以 DataLad 数据集的形式分发。
  • 项目中嵌套了其他数据集,并且你希望每个数据集都保留自己的独立历史记录。

如果仓库只包含代码和文本,所有内容都能轻松纳入 Git,且不需要部分检出,就使用普通 Git。在小型纯代码仓库上使用 DataLad 只会增加间接层,并无额外收益。

安装

# git-annex is NOT written in Python but is available from PyPI if you already
# have git itself installed:
uv pip install git-annex
# You can also install it first from the system
# (Debian/Ubuntu: apt install git-annex; macOS: brew install git-annex;
#  conda-forge: conda install -c conda-forge git-annex)
uv pip install datalad
uv pip install datalad-container   # only for containers-run

datalad wtf --section dependencies   # confirm git-annex version is visible

PyPI 的 git-annex 包将预构建的二进制文件作为 wheel 提供,适用于 Linux、macOS 和 Windows,而不是构建 Haskell 源码;因此,它的安装方式与其他 Python 依赖项相同,也可以与 DataLad 一起固定在同一环境中。它不会附带 git。

当行为看起来不可思议时,首先运行 datalad wtf,它会打印解析后的环境信息。许多令人困惑的错误都源于 git-annex 版本过旧或缺失。

DataLad 本身采用 MIT 许可证。git-annex 是一个采用 AGPL 许可证的独立工具,只有在你重新分发修改后的 git-annex(而非调用它)时,这一点才有影响。

最先遇到的问题:指针不是数据

执行 datalad clone 后,annex 管理的文件会以符号链接的形式存在,指向 .git/annex/objects/(在 Windows 或受限文件系统等不支持符号链接的环境中,则会显示为小型指针文件)。此时尚未下载任何内容。

datalad clone https://github.com/OpenNeuroDatasets/ds000001.git
cd ds000001
ls sub-01/anat/            # the file is listed
python -c "import nibabel; nibabel.load('sub-01/anat/sub-01_T1w.nii.gz')"   # fails
datalad get sub-01/anat/sub-01_T1w.nii.gz                                   # now it works

需要识别的一种故障情况是:工具报告文件为空、已截断、损坏、“不是 gzip 文件”或符号链接已失效,而磁盘上的文件只有几百字节。这是一个指针,而不是损坏的下载。读取数据前运行 datalad get,并且不要仅凭“文件存在”就断定其内容已就绪。

在分析访问某个目录之前,先显式获取该目录的内容:

datalad get sub-01/                  # everything under a path
datalad get -r .                     # everything, including subdatasets
datalad get -n -r .                  # subdataset structure only, no file content

datalad status --annex 会报告本地已有多少内容;git annex whereis <path> 会报告哪些仓库保存了指定文件。whereis 读取的是记录的状态,不会联系远程端,因此它告诉你的是 git-annex 上次获知的信息,而非当前的实际情况。

请参阅 data-access.md,了解如何查找数据集、子数据集的行为、安全地删除内容以及修复数据集。

使用 datalad run 记录溯源信息

在方法学场景中,使用 DataLad 的理由就在于 datalad run。它会将命令及其效果保存在同一个提交中:

datalad run -m "extract brain mask" \
  --input "sub-01/anat/sub-01_T1w.nii.gz" \
  --output "derivatives/sub-01_brain.nii.gz" \
  "bet {inputs} {outputs} -m"

各部分的作用,以及省略它们带来的影响:

  • --input 会在运行前获取内容,因此命令不会因遇到指针而失败。它还会记录依赖项,这样 rerun 才能在另一台机器上获取相同的输入。
  • --output 会先解锁或移除目标,因此 git-annex 不会拒绝覆盖它正在保护的内容。若省略此选项,再次运行相同命令时,通常会因 annex 管理的文件看起来是只读的而遇到权限错误。
  • {inputs} 和 {outputs} 会展开为对应的值。还可以使用 {pwd}、{dspath} 和 {tmpdir},并通过 {inputs[0]} 索引单个条目。
  • 提交消息会在 === Do not change lines below === 和 ^^^ Do not change lines above ^^^ 之间包含一条 JSON 运行记录。不要手动编辑这个代码块;rerun 会解析它。

当数据集存在未保存的修改时,datalad run 会拒绝启动,因为不干净的初始状态会导致记录不可靠。请先保存或丢弃修改,或者传入 --explicit,声明列出的输入和输出就是全部内容。使用 --dry-run basic 或 --dry-run command 检查命令,再决定是否提交。

如果运行没有产生任何更改,就不会创建提交,与 datalad save 的行为完全相同。

重新执行
datalad rerun                       # redo the run recorded at HEAD
datalad rerun --report              # show what would be done, change nothing
datalad rerun --script recompute.sh # extract the commands instead of running them
datalad rerun --since <commit> -b check <revision>   # replay a range onto a new branch

在一个分支上重新运行(-b)是测试可复现性的安全方法:重放结果会落在其他位置,与原始分支进行比较,即可判断输出是否完全一致。

容器

使用 datalad-container 扩展时,只需注册一次镜像,之后的每次运行都会记录生成输出所用的镜像:

datalad containers-add fsl --url docker://brainlife/fsl:6.0.4
datalad containers-run -n fsl -m "brain mask in container" \
  --input "sub-01/anat/sub-01_T1w.nii.gz" \
  --output "derivatives/sub-01_brain.nii.gz" \
  "bet {inputs} {outputs} -m"

镜像本身会在数据集中进行跟踪,因此软件环境会与数据和溯源记录一同保存,而不是只留在某人的 shell 历史记录中。如果只配置了一个容器,可以省略 -n。

请参阅 provenance.md,了解 STAMPED 原则和 YODA 项目布局、运行记录格式、--explicit 和 --assume-ready 的语义,以及如何将溯源信息导出为 W3C PROV。

保存和检查更改

datalad status                 # what changed, including subdataset state
datalad save -m "add QC report" path/to/file
datalad save -m "checkpoint" -r                 # recurse into subdatasets
datalad save -m "small text file" --to-git notes.md

datalad save 会根据数据集的 .gitattributes,逐个文件判断内容应存入 Git 还是 git-annex。使用 --to-git 可强制将文件存入 Git;对于代码和应保持可直接读取的小型文本文件,这是正确的选择。yoda 程序(datalad create -c yoda)会自动为 code/、README.md 和 CHANGELOG.md 设置此规则。

创建数据集

datalad create my_dataset               # plain dataset
datalad create -c yoda my_analysis      # analysis layout (code/ tracked in Git,
                                        # README.md and CHANGELOG.md preconfigured)
datalad create -d . inputs/raw          # register a new subdataset under an existing one

-c yoda 会应用 provenance.md 中介绍的分析项目布局。-d . 会将新数据集注册为父数据集的子数据集,而不是在其中留下一个无关的代码仓库。

发布

DataLad 数据集通常会同时发布到两个位置:用于存储历史记录的 Git 托管服务,以及用于存储 annex 内容的存储远程端。

datalad create-sibling-github myaccount/mydataset
git annex initremote store type=S3 bucket=my-bucket encryption=none autoenable=true
datalad siblings configure -s github --publish-depends store
datalad push --to github

Git sibling 和存储 sibling 是有意通过不同工具创建的。Git sibling 是 Git 远程端,datalad create-sibling-* 用于创建托管服务上的远程端。S3 存储桶(或 WebDAV、SSH 目录)是 git-annex 特殊远程端,而不是 Git 远程端,因此要用 git annex initremote 创建。之后,datalad siblings 会找到这个特殊远程端,并像对待其他远程端一样处理它。在这里使用 datalad siblings add --url s3://... 正是本节要避免的错误:--url 接受的是 Git 远程端 URL,而 S3 不是 Git 远程端,因此后面的 push --to github 会在 --publish-depends 环节失败。

--publish-depends 可以避免一种常见的发布故障:Git 仓库的历史记录引用了尚未上传的内容,导致协作者成功克隆后,所有 datalad get 命令却都失败。声明此依赖后,每次都会先发布存储 sibling。

datalad push 会发送 Git 历史记录,并且默认情况下(--data auto-if-wanted)也会发送目标配置为需要的 annex 内容。传入 --data anything 可忽略目标的偏好,推送所有内容。

有关 RIA 存储、特殊远程端、凭据处理以及配置各 sibling 的存储内容,请参阅 publishing.md。

释放磁盘空间

git annex whereis sub-01/                 # confirm another copy exists first
datalad drop sub-01/                      # remove local content, keep the pointer
datalad drop --what all --reckless kill <path>   # last resort, destroys data

默认情况下,如果 datalad drop 无法确认内容存在其他副本,就会拒绝执行;这是安全检查,而非阻碍。--nocheck 和 --if-dirty 已弃用;目前的写法是 --reckless availability,含义正如其名。--what 可在 filecontent(默认值)、allkeys、datasets 和 all 之间进行选择。

值得了解的故障模式

现象原因修复方法
文件读取结果为空、被截断或是损坏的符号链接未检索内容;只有指针存在datalad get <path>
写入现有输出时出现“Permission denied”git-annex 会对 annex 内容启用写保护使用 --output 声明该文件,或执行 datalad unlock <path>
datalad run 拒绝启动数据集有未保存的更改先运行 datalad save,或传入 --explicit
datalad drop 拒绝执行没有已验证的第二份内容副本先推送到一个 sibling,或接受 --reckless availability
协作者克隆成功,但每个 get 都失败发布了历史记录,却未发布内容发布存储 sibling,并设置 --publish-depends
克隆成功,但子数据集目录为空默认不会安装子数据集执行 datalad get -n -r .,然后对所需路径执行 get
命令行为异常缺少 git-annex 或其版本过旧datalad wtf --section dependencies

详细参考

  • data-access.md:查找已发布的数据集(registry.datalad.org、OpenNeuro、DANDI、datasets.datalad.org 和 /// 快捷方式)、克隆和 get 选项、子数据集处理、annex 内容状态、丢弃和删除,以及 fsck 修复。
  • provenance.md:STAMPED 原则和 YODA 布局、运行记录格式、run 和 rerun 的完整选项、containers-run,以及将 DataLad 来源信息导出为 W3C PROV 的当前进展。
  • publishing.md:sibling 及其操作、create-sibling-* 各变体、RIA 存储、特殊远程端、push 语义和凭据处理。

相关技能

bids 技能介绍了 Brain Imaging Data Structure;通过 DataLad 分发的大多数神经影像数据集都按该结构组织。典型工作流是使用 DataLad 克隆一个 BIDS 数据集,使用 BIDS 工具验证,然后通过 datalad containers-run 运行 BIDS-App,使衍生数据带有来源信息。

主要来源

致谢

此技能的主题范围部分参考了 @bcmcpher 基于 MIT 许可证发布的 datalad-cli 插件(包含 19 个按命令划分的斜杠命令技能)。本文独立撰写,并以 DataLad 上游文档为依据;由于两者都涉及 DataLad,内容难免有所重叠,但结构、风格和具体技术主张各不相同。

Agent 操作流程

  1. 检查环境。 确认 Python 环境和库版本(python -c "import pkg; print(pkg.__version__)"),并检查数据的形状、类型和缺失值。
  2. 明确输入。 根据数据或用户确认格式、标识符和参数。任何会改变结果的值都应询问,而不是猜测。
  3. 先运行小规模版本。 先在样本或单个折上运行,并检查运行时间和内存使用情况。
  4. 使用上述说明和参考资料 执行完整任务。
  5. 验证结果。 使用留出数据、固定随机种子和恰当的指标;检查数据泄漏;报告不确定性(置信区间、不同随机种子下的标准差)。
  6. 报告。 说明运行了什么(版本、命令、参数)、检查了什么,以及仍有哪些不确定之处。
如果发生这种情况请这样做
内存不足或执行速度很慢进行子采样,使用分块或惰性计算,或缩小模型规模,并告知用户做了哪些更改。
这些说明中的函数、标志或端点在已安装版本中不存在查阅已安装版本自身的文档(help()、--help、官方文档),进行调整并告知用户。切勿编造 API。
所需的输入、标识符或参数含义不明确询问用户,或在运行前明确说明所作假设。

完整性规则

  • 切勿捏造结果、参数、标识符、引用或统计数据。如果某项内容无法运行或验证,请明确说明。
  • 切勿报告本次会话中未计算的指标;请展示生成每个数值的代码路径。
  • 将此处的版本相关细节视为可能已过时:请根据已安装版本的官方文档进行确认。
  • 对于会产生费用、占用共享 GPU 或云配额、涉及个人或患者数据,或无法撤销的操作,务必事先征求同意。

评论

支持 Markdown