Repository navigation
Description
Tracks upstream friction in TinyDB. The explanation lives in the docs; this issue is the unit of work.
Explanation: Table.update_multiple() cannot select documents by id — the limitation, why it matters to an ODM, the workaround tinydantic carries, and the change that would remove it. That section is written to be read standalone by an upstream maintainer, so it doubles as the ready-to-send proposal if we ever file this.
Reproduction
Upstream only — the limitation is in the signatures.
import inspect
from tinydb.table import Table
for name in ("update", "remove", "update_multiple"):
print(f"{name:16}{inspect.signature(getattr(Table, name))}")Run with python repro.py.
Actual output:
update (self, fields: Union[collections.abc.Mapping, collections.abc.Callable[[collections.abc.MutableMapping], None]], cond: Optional[tinydb.queries.QueryLike] = None, doc_ids: Optional[collections.abc.Iterable[int]] = None) -> list[int]
remove (self, cond: Optional[tinydb.queries.QueryLike] = None, doc_ids: Optional[collections.abc.Iterable[int]] = None) -> list[int]
update_multiple (self, updates: collections.abc.Iterable[tuple[typing.Union[collections.abc.Mapping, collections.abc.Callable[[collections.abc.MutableMapping], None]], tinydb.queries.QueryLike]]) -> list[int]
update() and remove() both take doc_ids. update_multiple() — the only batched write, and the only one that runs in a single atomic read-modify-write cycle — takes (fields, cond) pairs and nothing else. Combined with the id-invisibility limitation (#133), there is no way to target documents by id in a batched update: not by condition, and not by selector.
Expected: an id selector in the batched form — a third element in each pair, or a parallel update_multiple_by_ids() — mirroring what update() and remove() already accept.
Environment: TinyDB 4.9.0, Python 3.10.20, macOS. Run 2026-08-13.
What tinydantic carries today
The private-API write cycle. Table.update_multiple() takes only (fields, cond) pairs, and conditions cannot see ids (#133), so there is no public way to run a batched id-targeted write in one atomic read-modify-write cycle.
Private API: Table._update_table(updater) in TinydanticModel._run_write_cycle() — backs all of tinydantic's update()/update_by_ids()/update_all()/update_many() writes plus the id-condition paths of remove() and upsert(). Approved 2026-07-13, scope extended 2026-08-02. Also the only way to validate-then-write atomically; benchmarked ~23% faster than the two-pass public alternative.
Upstream status
Not filed. No draft prepared.
What would close this
Either a per-pair id selector on Table.update_multiple(), or the needs_doc_id/DocId protocol combined with a public batched read-modify-write API — or a maintainer decision to carry the workaround indefinitely.
Assisted-by: Claude:claude-opus-5
Activity
[-]upstream(tinydb): update_many() cannot select documents by id[/-][+]upstream(tinydb): Table.update_multiple() cannot select documents by id[/+]docs(query): correct matches() semantics and query docstrings