Rows present does not mean the business operation completed
An operations owner may see every imported row but discover that a derived label, internal audit entry or related count is missing. Identify the specific expected update and the path that writes it. This is different from a slow import or a transaction that never committed.
- Compare the import's bulk_create/bulk_update path with an ordinary save on one invented record.
- Inventory custom save methods and pre_save/post_save receivers needed for that result.
- Separate internal database effects from customer messages or other external actions before testing.
Bulk writes have a different contract
Django documents that these bulk operations do not call each model's save method and do not emit its usual save signals. Reintroducing a loop can change performance and side effects; blindly emitting signals after a bulk operation can also duplicate work or operate on an incomplete result. Decide which business rule must be explicit in the import rather than relying on an incidental signal.
- Confirm the installed Django and database versions before relying on returned IDs or conflict behaviour.
- Include duplicate inputs and an existing-row update in the agreed fixture if relevant.
- Do not assume batch_size creates committed, recoverable business checkpoints.
Define one missed invariant
An authored regression uses two invented rows and states the exact derived value or internal audit count expected after import. Capture the failure on the unfixed revision, then the passing result and one ordinary-save comparison. A passing row count alone is insufficient. No import has been executed for this candidate.
- Disable captured external effects on the isolated copy.
- Record whether retrying the same import is allowed and what must remain unchanged.
- Do not replay a live import to discover which invoices or emails it might recreate.
Non-fit and priced route
One ordinary missed internal update that repeats with synthetic fixtures may fit fix-one-bug-with-regression-test, from £295 after bounded reproduction and a fixed repair quote. A new import architecture, performance project, production-data correction or backlog replay does not fit that offer; ask the existing operator to define a separate recovery or redesign scope. An enquiry needs the missed invariant and framework version, not a data export or source code.
- Prices remain untested proposals; payment follows agreed passing checks and sign-off.
- Authoritative technical behaviour is not evidence of a buyer request or previous SI delivery.
Sources and limits
- Django 5.2 QuerySet reference: bulk_create and bulk_update; BSD-licensed project documentation Checked 2026-10-11.
- bulk_create does not call each model's save method or send pre_save/post_save signals.
- bulk_update uses QuerySet.update and similarly bypasses per-object save and save signals.
- Bulk operations have batching and model-relation limitations.
- Current single-bug offer and replay exclusions Checked 2026-10-11.