civex.upsert_records
Create or update records from a DataFrame, matching existing records by a key field. If a record with the same key exists in the collection, it is updated; otherwise a new record is created. Reach for this over civex.rows_to_records when the same source table gets re-imported over time, e.g. a selection table that grows across a field season.
Uses pandas, which ships with civex — see
civex.parse_table.
Plugin ID: civex.upsert_records
Category: outputs
Capabilities: create_record, update_record, find_records
Config
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
schema |
string | yes | Name of the schema to create/update records under. Workflow YAML sets this via the schema: key (the Python field is schema_name). |
|
key_field |
string | yes | Field used to match table rows against existing records. | |
dataset |
string | no | "" | Dataset to search and create records in. Empty string falls back to the trigger record's own dataset. |
parent_record_id |
string | no | "" | Parent record ID to scope matching and creation to. Empty string falls back to the trigger record's ID. |
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
table |
table | yes | Rows to upsert; columns map to schema fields by name. |
Outputs
| Name | Type | Required | Description |
|---|---|---|---|
created |
number | yes | Rows that inserted. |
updated |
number | yes | Rows that matched. |
skipped |
number | yes | Rows whose record failed validation. |
- id: upsert
plugin: civex.upsert_records
config:
schema: Selection
key_field: selection_number
inputs:
table: parse.table
What an update keeps
An update changes only the columns in the table. Every other field on the matched record (a file, values computed by another workflow) is left exactly as it is, and an empty cell leaves its field alone instead of clearing it. A row whose values are already on the record changes nothing: no history entry, and no workflow triggered. Only a cell with a value is ever written.