You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
save(only=) / save(exclude=) emit columns in set order, so the UPDATE text changes between runs #776
save(only={...}) and save(exclude={...}) take a set of column names, and the UPDATE they send lists the columns in that set's iteration order, which changes between Python processes:
awaitaccount.save(only={"label", "balance"})
# one run: UPDATE "account" SET "label" = $1, "balance" = $2 WHERE "id" = $3# another run: UPDATE "account" SET "balance" = $1, "label" = $2 WHERE "id" = $3
The row ends up the same, but the statement text does not. That surfaced while pinning the Mutations guide's SQL blocks (#725, PR #775): the docs test has to run with PYTHONHASHSEED=0 to get a stable statement, and the page tells readers the column order is not fixed. The statement log and .sql() show a different statement for the same call from one process to the next, which makes log diffs and any test asserting on the SQL flaky.
What this asks for
A write's column order is a function of the model, never of a set's hash order: only= / exclude= columns are emitted in the model's field declaration order (the order save() without only= already uses). Then the docs test drops PYTHONHASHSEED=0, and the Mutations page's sentence about unfixed order goes.
Worth checking at the same time: any other write that takes a set (bulk_create with only=/exclude=, if it does) and whether update(**fields) follows the call's keyword order (it should: keyword order is deterministic).
The worker on Show captured SQL beside query and mutation examples (needs #700) #725 also noted that exists() sends COUNT(*) rather than SELECT 1 … LIMIT 1 (a performance observation, not a correctness one), and that a batch update() does not refresh an instance the session already holds (identity-map staleness after a set-based write). Both may deserve their own issues.
Status: verify-passed Worker: fix-src (epic #698, panel round 1 on #777) Branch:sdd/698-fix-src-round-1 PR:#779 Verify: passed 88ae5e5 (reviewer re-run, SQLite and Postgres; trial merge not run, base unchanged) Review: Spec PASS, Quality PASS (three Minors) — #779 (review)
Every write now lists its columns in field declaration order: save(), save(only=), save(exclude=) and bulk_create. There were three causes: the only=/exclude= set, a fetched instance's alphabetical __dict__, and bytes/secret columns appended last.
The docs SQL gate no longer pins PYTHONHASHSEED. The Mutations blocks are regenerated and the unfixed-order sentence is gone.
Pinned by tests/test_save_column_order.py on SQLite and Postgres.
Activity
0x054 commentedon Oct 21, 2026
Status: verify-passed
Worker: fix-src (epic #698, panel round 1 on #777)
Branch:
sdd/698-fix-src-round-1PR: #779
Verify: passed 88ae5e5 (reviewer re-run, SQLite and Postgres; trial merge not run, base unchanged)
Review: Spec PASS, Quality PASS (three Minors) — #779 (review)
Every write now lists its columns in field declaration order:
save(),save(only=),save(exclude=)andbulk_create. There were three causes: theonly=/exclude=set, a fetched instance's alphabetical__dict__, and bytes/secret columns appended last.The docs SQL gate no longer pins
PYTHONHASHSEED. The Mutations blocks are regenerated and the unfixed-order sentence is gone.Pinned by
tests/test_save_column_order.pyon SQLite and Postgres.fix: panel round 1 on #777 (src) — restore status flags and PoolConfi…
0x054 commentedon Oct 21, 2026
Fixed in #779, merged into
feat/docs-rewrite(c80e3eb); reachesmainwith PR #777.