Subchapter 21.1
references/data-table-playbook.mdMarkdown6 KBView on GitHub
Use this reference when the table needs design judgment, import mapping, cleanup, or a careful mutation. Keep the working set small: list/schema first, then use IDs and narrow filters.
list.listschemaquerylist -> design schema -> create.list -> schema -> insert-rows in batches of 100.parse-file preview -> list -> create/schema ->
insert-rows batches.list -> schema -> rename-column with columnId.list -> schema -> query count/sample ->
update-rows with the same precise filter.list -> schema -> query count/sample ->
delete-rows with the same precise filter.list -> delete with dataTableName.list -> schema -> add-column for missing
columns / delete-column for extras; for a wrong column type, delete +
create when the table is empty, or stop and ask when it holds data.Columns:
first_name stringlast_name stringemail stringphone stringcompany stringsource stringstatus stringcreated_date dateUse email or external_id for matching. Keep phone as string.
Columns:
order_id stringcustomer_email stringamount numbercurrency stringstatus stringordered_at dateexternal_id stringKeep order_id as string even when numeric-looking.
Columns:
ticket_id stringrequester_email stringsubject stringpriority stringstatus stringassigned_to stringcreated_at_source datelast_error stringAvoid created_at to stay away from system-like names.
Columns:
external_id stringsource stringstatus stringattempt_count numberprocessed_at datelast_error stringpayload_json stringUse this for idempotency, retries, and “do not process twice” workflows.
Columns:
key stringvalue stringdescription stringis_active booleanUse lookup tables for stable routing/config values, not high-volume event logs.
Before creating or inserting from a file preview:
email_2, but prefer a
semantic name when obvious, e.g. billing_email and shipping_email.string for postal codes, phone numbers, IDs, currency strings, and
mixed values.date only when all non-empty samples are dates.string, not boolean, even if samples
contain only two values. Future rows often add a third state.payload_json only if preserving the full payload is
part of the user request.For large files, report progress plainly:
Imported 1,000 rows into Leads. The file has more rows; import stopped at the 10-page safety limit with nextStartRow=1001.Create a designed table:
1. data-tables list
2. data-tables create { name, projectId?, columns }Import a CSV into a new table:
1. parse-file { attachmentIndex: 0, maxRows: 20 }
2. data-tables list
3. data-tables create with chosen column names/types
4. data-tables insert-rows, max 100 rows
5. parse-file next page with startRow=nextStartRow; repeat up to safety limitImport into an existing table:
1. data-tables list
2. data-tables schema with dataTableId; projectId is optional when dataTableId is present
3. parse-file preview
4. Map source columns to existing schema names
5. insert-rows in batches of 100Update rows:
1. data-tables schema
2. data-tables query with precise filter and small limit
3. If matches are right, data-tables update-rows with the same filter and dataDelete rows:
1. data-tables schema
2. data-tables query with precise filter and small limit
3. If matches are right, data-tables delete-rows with the same filteradd-column; remove extras with delete-column.
Column types cannot be changed in place; for an empty or just-created table,
delete then create with the correct columns; for a populated table, stop
and ask before recreating. Never weaken a workflow’s design to fit a wrong
schema.nextStartRow.Creation:
Created Leads with 6 columns: first_name, last_name, email, company, status, created_date.Import:
Imported 240 rows into Leads from the attached CSV. Skipped 3 rows with empty
required values.Blocked or denied:
No rows were deleted. The delete action was denied.Ambiguous mutation:
I found 37 matching rows. Which status should I update: all of them, or only a
smaller subset?Workflow handoff:
Created Order Queue (ID: dt_123) in Sales Ops with order_id, customer_email, amount, currency, status, and processed_at. Use order_id for idempotent lookups.