Batch writes
batch runs a list of writes in order, each one seeing the previous ones. If the engine refuses one, it undoes the ones already applied, so the batch succeeds or fails as a whole. The batch is one journal entry: undo_migration reverts all of it, and a dry run checks each operation against the current data. Concurrent writes explains how a batch meets the writes of other clients.
Group several writes with batch
Section titled “Group several writes with batch”batch runs writes in order, and each write sees the ones before it. If the engine refuses one, it undoes those already applied and leaves nothing written. The whole batch has one migration_id.
batch
{ "summary": "watch Charade, add Night of the Living Dead, rate Sherlock Jr.", "operations": [ { "op": "update_row", "table": "film", "path": "datanotes/main/public/film/Charade.md", "set": { "status": "watched", "rating": 4 } }, { "op": "insert_row", "table": "film", "values": { "title": "Night of the Living Dead", "year": 1968 } }, { "op": "update_row", "table": "film", "path": "datanotes/main/public/film/Sherlock Jr..md", "set": { "rating": 9 } } ]}Refused:
batch refused at operation 2 — the operations before it were undone, nothing is left written:operation 2 (update_row): update_row refused — nothing was written:invalid datanotes/main/public/film/Sherlock Jr..md: rating must be <= 5Hint: Give a value inside the column's range (the message names the bound); describe_table shows its min and max. Then call update_row again (dry_run: true checks without writing).Docs: https://datanotes.dev/guides/database-objects/tables.md#describe-a-table-before-writing-to-it (offline: read_docs("guides/database-objects/tables#describe-a-table-before-writing-to-it"))Hint: Nothing is left written: fix operation 2 as its error says, then send the whole batch again.Docs: https://datanotes.dev/guides/read-and-write/batch.md#group-several-writes-with-batch (offline: read_docs("guides/read-and-write/batch#group-several-writes-with-batch"))The engine refused the third write (rating is at most 5), so it undid the first two:
select_rows
{ "table": "film", "columns": ["title", "status"], "where": { "title": { "in": ["Charade", "Night of the Living Dead"] } }}Answer:
{ "table": "main.public.film", "total": 1, "rows": [ { "path": "datanotes/main/public/film/Charade.md", "title": "Charade", "status": "to watch" } ]}dry_run: true checks a batch without writing it. Without the bad write, the batch goes through:
batch
{ "dry_run": true, "operations": [ { "op": "update_row", "table": "film", "path": "datanotes/main/public/film/Charade.md", "set": { "status": "watched", "rating": 4 } }, { "op": "insert_row", "table": "film", "values": { "title": "Night of the Living Dead", "year": 1968 } } ]}Answer:
{ "ok": true, "op": "batch", "dry_run": true, "steps": [ { "index": 0, "op": "update_row", "ok": true, "result": { "ok": true, "op": "update_row", "dry_run": true, "planned_edits": [ { "path": "datanotes/main/public/film/Charade.md", "set": { "status": "watched", "rating": 4 }, "remove": [] } ] } }, { "index": 1, "op": "insert_row", "ok": true, "result": { "ok": true, "op": "insert_row", "dry_run": true, "planned_creates": ["datanotes/main/public/film/Night of the Living Dead.md"] } } ]}