Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions skills/hotdata/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,9 @@ hotdata ingest create --datasource-id ds_01J --type one-time \
# selector.json is family-specific (what subset to read) — its fields, and the
# write modes this family accepts: hotdata ingest sources fields <family>.
# destination.json is {"database_id", "schema", "table", "write_mode"} —
# write_mode: replace | upsert (upsert needs a continuous bucket ingest).
# write_mode (default replace): replace|append work on any table; the key-based
# modes upsert|update|delete need the destination table to have a declared key.
# `hotdata ingest sources fields <family>` reports which modes the family accepts.
# Selector and destination are both IMMUTABLE after creation.
# CREATE STARTS NOTHING, for every type. It returns no run id, and
# `ingest logs <id>` is EMPTY until the scheduler claims the ingest — normal,
Expand All @@ -328,7 +330,9 @@ hotdata ingest create --source "prod postgres" --table orders --schema public \
# --limit N stop after N source rows
# Destination flags instead of --destination:
# --database-id (required) --dest-table (defaults to the single --table)
# --dest-schema (default public) --write-mode (default replace)
# --dest-schema (default public)
# --write-mode replace|append|upsert|update|delete (default replace; upsert/
# update/delete need the destination table to have a declared key)

hotdata ingest create --datasource-id ds_01J --database-id db_123 \
--sql "SELECT id, status FROM public.orders WHERE status = 'open' LIMIT 1000"
Expand Down
22 changes: 13 additions & 9 deletions src/commands/ingest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,15 +238,19 @@ pub enum IngestCommands {
#[arg(long = "dest-schema")]
dest_schema: Option<String>,

/// How each run writes (default: replace). `upsert` needs a family
/// whose load path stamps a row key — today that is a continuous bucket
/// ingest, and `hotdata ingest sources fields <family>` reports which modes
/// a family accepts for which type.
///
/// The two listed are the two the destination accepts anywhere. Offering
/// a third would be offering a request that is refused on arrival, which
/// costs the user a round trip to learn what `--help` could have said.
#[arg(long = "write-mode", value_parser = ["replace", "upsert"])]
/// How each run writes (default: `replace`). `replace` and `append` work
/// on any destination table; the key-based modes `upsert`, `update`, and
/// `delete` match rows by the table's declared key and are rejected on a
/// keyless table. This list is the service-wide vocabulary — clap catches a
/// typo up front — but which of these a *given* family or table accepts is
/// reported by `hotdata ingest sources fields <family>`, the authoritative
/// source; a mode the family or table does not support is refused on
/// arrival. (The old list `[replace, upsert]` both omitted `append` — which
/// families advertise — and offered `upsert` as if universal: see #278.)
#[arg(
long = "write-mode",
value_parser = ["replace", "append", "upsert", "update", "delete"]
)]
write_mode: Option<String>,

/// Schedule as JSON (inline, @file.json, or @-):
Expand Down
Loading