一键导入
import-tasks
Write xronos:import:* rake tasks using ImportRunner — import external datasets from CSV and BibTeX with provenance tracking and PaperTrail auditing.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Write xronos:import:* rake tasks using ImportRunner — import external datasets from CSV and BibTeX with provenance tracking and PaperTrail auditing.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Work with the LinkedResource model, the LinkedResource::Source registry, the Linkable concern, and the BatchMatchableToWikidata concern in XRONOS. Use when adding new linked data sources (Pleiades, Vici.org, OpenContext, iDAI.gazetteer, etc.), working with the curation dashboard, refactoring the linked_resources form, or attaching the linkable macro to a new model.
Work with the ControlledVocabulary model family and the HasControlledTerms concern in XRONOS. Covers the strict-vs-fuzzy matching split, the variant thesaurus, normalization rules, and how to add new controlled-term-backed attributes. Use when adding, seeding, querying, or refactoring any controlled-vocabulary-backed attribute.
基于 SOC 职业分类
| name | import-tasks |
| description | Write xronos:import:* rake tasks using ImportRunner — import external datasets from CSV and BibTeX with provenance tracking and PaperTrail auditing. |
| license | MIT |
Import tasks are create-only. They never update existing records — any variation in source data produces a new record (matched across all keys + attributes). Duplicate resolution is handled separately.
Inspect all files (CSV headers + sample rows, BibTeX keys, documentation). If a column's meaning is unclear, ask the user. If the data contains types that don't exist in XRONOS's model, ask the user whether to add them.
After mapping known columns to XRONOS models, list any unused columns to the user — they may contain overlooked data or be ignorable noise.
cell(row, "Column") for all CSV cell access (strips whitespace, returns nil for blanks).skip_unless condition, "reason" (counts and reports skipped rows).&.to_i / &.to_f for numeric conversions after cell().find_by + update — always use import!.Follow the skeleton below. Every task takes three required arguments: [version, dir, source_url].
Create a bibliographic reference for the source dataset itself (Phase 0 in the skeleton, using BibTeX provided by the source authors). Store it on the Source record, then call cite_source!(record) after creating each citable record.
require "bibtex" # if BibTeX files are used
namespace :xronos do
namespace :import do
desc "Import MyDataset"
task "mydataset", [:version, :dir, :source_url] => :environment do |t, args|
version, dir, source_url = Xronos::ImportRunner.parse_args!(args)
source = Source.register(
name: "MyDataset",
version: version,
path: dir,
source_url: source_url,
license: "CC-BY 4.0",
notes: "MyDataset: description"
)
admin_user_id = ENV.fetch("ADMIN_USER_ID") { abort "ADMIN_USER_ID must be set" }
revision_comment = "Imported from MyDataset #{version} <#{source_url}>"
PaperTrail.request(whodunnit: admin_user_id) do
runner = Xronos::ImportRunner.new(source, csv_dir: dir)
begin
runner.describe!(whodunnit: admin_user_id, revision_comment: revision_comment)
# Phase 0: Source reference
source_ref = runner.import!(Reference,
keys: { short_ref: "MyDataset" },
attributes: { bibtex: <<~BIB.chomp
@article{Author2023,
author = {Author, A. and Author, B.},
title = {Title},
doi = {10.xxxx/xxxxx}
}
BIB
},
revision_comment: revision_comment
)
source.update!(reference: source_ref)
# === Import data phases here (use csv/process_enum with instance_exec blocks) ===
runner.succeed!
runner.report!
rescue => e
runner.import_record.update!(error: "#{e.class}: #{e.message}")
raise
end
end
end
end
end
csv, process_enum) via instance_exec| Method | Purpose |
|---|---|
import!(scope, keys:, attributes: {}, revision_comment: nil) | Create-only import; finds by merged keys+attributes, creates on miss |
cell(row, column) | Sanitise CSV cell: strip whitespace, blank → nil |
skip_unless(condition, reason) | Guard clause: throw :skip_row unless condition is truthy; counts skipped rows by reason in records_skipped |
cite_source!(citable) | Link a citable record to the source's reference (must set source.reference first) |
import_record | Current Import audit record |
runner (or ImportRunner) outside blocks| Method | Purpose |
|---|---|
Xronos::ImportRunner.parse_args!(args) | (class method) Extract version, dir, source_url from task args; aborts with usage on missing args or missing dir |
csv(filename, **csv_options, &block) | Iterate CSV with progress bar; options forwarded to CSV.foreach |
process_enum(enumerable, title:, &block) | Iterate any enumerable with progress bar |
describe!(whodunnit:, revision_comment:) | Print pre-import options header |
report! | Print post-import ASCII table of created records |
succeed! | Mark import as successful, persist counters |
Test import! directly via ImportRunner:
test "creates records for attribute variations" do
runner = Xronos::ImportRunner.new(source, csv_dir: tmpdir)
a = runner.import!(Site, keys: { name: "Alpha" }, attributes: { lat: "10.5" })
b = runner.import!(Site, keys: { name: "Alpha" }, attributes: { lat: "99.9" })
assert_not_equal a.id, b.id
assert_equal 2, runner.import_record.records_created["site"]
end
test "does not duplicate identical data" do
runner = Xronos::ImportRunner.new(source, csv_dir: tmpdir)
a = runner.import!(Site, keys: { name: "Alpha" }, attributes: { lat: "10.5" })
b = runner.import!(Site, keys: { name: "Alpha" }, attributes: { lat: "10.5" })
assert_equal a.id, b.id
assert_equal 1, runner.import_record.records_created["site"]
end
test "skip_unless skips row and counts reason" do
write_csv("samples.csv", [%w[Name BP], %w[Alpha 100], %w[Beta], %w[Gamma 200]])
kept = []
runner = Xronos::ImportRunner.new(source, csv_dir: tmpdir)
runner.csv("samples.csv") do |row|
skip_unless cell(row, "BP"), "missing BP"
kept << cell(row, "Name")
end
assert_equal %w[Alpha Gamma], kept
assert_equal 1, runner.import_record.records_skipped["missing BP"]
end
See lib/tasks/import/14canarias.rake for the canonical example.
If you add new shared helpers to ImportRunner or change the task skeleton convention, update this skill file so future agents use the correct patterns. The skill is the single source of truth for import task conventions.