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
Commit ccf026c
Browse filesBrowse the repository at this point in the historyBrowse files
docs: correct the find, errors, fields, and storage docstrings
_find.py:
- F1 delete() claimed "an empty window is a no-op returning [] with
zero storage writes" and that its two paths are "observably
identical". The condition-only path runs before the empty-window
check and reaches Table.remove(cond=…), which writes the table
back whether or not anything matched. Measured with
ProfilingMiddleware: 1 write on the condition path, 0 on the
resolved-ids path. Now describes both and points at #145, which
tracks making it zero.
- F2/F3 the module and class docstrings predate filter(): "each
clause is stated once" is true of ordering and window only, and
filter() appeared in neither the modifier nor the terminal list.
- F4 FindQuery.update()'s Raises omitted RevisionUpdateError.
- F5 "honouring" -> "honor". F6 a rejection compared to a rule.
_errors.py:
- E1 SelectorError's docstring described a removed API four ways:
it listed get_or_raise() (deleted this cycle), named get() and
contains() as raisers (they take a required positional and raise
QueryTypeError), described a "conflicting selectors" arm with no
code path left, and illustrated it with get(doc_id=1,
doc_ids=[1]) — a call that is a plain TypeError. Rewritten
against the three real raise sites: update(), remove(), upsert().
- E2 DocumentIDRequiredError's raiser list omitted patch().
- E3 the summary line read as if "tuple" glossed "value".
_fields.py:
- FI1 both marker docstrings called update()/update_many() the
bypass; update_by_ids(), update_all(), and FindQuery.update()
bypass too. Same wording as _model.py and crud.md now.
- FI2 the only reST `::` literal block in src/. mkdocstrings
renders Markdown, so it published as a literal "case::".
tinydb/ and scripts/:
- T1 the ProfilingMiddleware stacking paragraph was exactly
backwards. TinyDB talks to the outermost wrapper. Measured over
one insert and five all() calls: outer 7 reads / 1 write, inner 2
reads / 0 writes. The same sentence was published on
docs/usage/storage.md (D-STOR-1).
- T2 YAMLStorage.__init__ said kwargs go to yaml.dump(); write()
uses yaml.safe_dump, and its own docstring explains why.
- T3 the access-mode note now says the inherited binary modes are
accepted without a warning and do not work.
- T4 "adaption" -> "adaptation".
storage.md also had two claims that do not hold:
- D-STOR-2 "TinyDB stores document ids as strings, so a table with
ten documents serializes "1", "10", "2"" was stated as a general
property. JSONStorage — the page's own default — writes "1"…"10"
in insertion order; lexicographic order comes from sorting
serializers such as yaml.safe_dump. Both verified.
- D-STOR-3 "kept free of any dependency on tinydantic's core" is
contradicted by ProcessLockMiddleware importing DatabaseLockedError
and TinydanticUserError. The note now names the one dependency.
- D-STOR-4 an open handle on Windows blocks deleting or renaming a
file, not opening it.
Assisted-by: Claude:claude-opus-5
Copy file name to clipboardExpand all lines: docs/usage/storage.md
+7-5Lines changed: 7 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -63,7 +63,7 @@ A file-backed TinyDB holds an open file handle. Call [close()][tinydb.database.T
63
63
64
64
> [!TIP]
65
65
>
66
-
> `TinyDB` supports the context-manager protocol: `with TinyDB('db.json') as db:` closes the file on exit. TinyDB flushes on every write, so an unclosed handle will not lose data — but closing it releases the OS file handle promptly, which matters for long-running processes and on Windows, where an open handle blocks other openers.
66
+
> `TinyDB` supports the context-manager protocol: `with TinyDB('db.json') as db:` closes the file on exit. TinyDB flushes on every write, so an unclosed handle will not lose data — but closing it releases the OS file handle promptly, which matters for long-running processes and on Windows, where an open handle blocks deleting or renaming the file.
67
67
68
68
## YAML files
69
69
@@ -125,7 +125,7 @@ Log(id=1, msg='cached')
125
125
126
126
### Keeping document ids in numeric order
127
127
128
-
TinyDB stores document ids as strings, so a table with ten documents serializes `"1"`, `"10"`, `"2"` — lexicographic order, which undoes much of the reason to choose a human-readable format in the first place. [SortIntDocIDsMiddleware][tinydantic.tinydb.middlewares.SortIntDocIDsMiddleware] converts the ids back to integers on write and inserts them in ascending numeric order:
128
+
TinyDB stringifies document ids before handing a table to the storage layer, so whether ten documents serialize in numeric or lexicographic order is up to the serializer. `JSONStorage` preserves insertion order and writes `"1"` … `"10"`; a serializer that sorts its keys — notably `yaml.safe_dump`, which sorts by default — writes `"1"`, `"10"`, `"2"`, which undoes much of the reason to choose a human-readable format in the first place. [SortIntDocIDsMiddleware][tinydantic.tinydb.middlewares.SortIntDocIDsMiddleware] converts the ids back to integers on write and inserts them in ascending numeric order, so both kinds of serializer agree:
129
129
130
130
```pycon
131
131
>>> from tinydantic.tinydb.middlewares import SortIntDocIDsMiddleware
@@ -147,7 +147,7 @@ tickets:
147
147
148
148
```
149
149
150
-
Without it, that file would open with `1`, `10`, `2`. The trade-off is in the name: the middleware hands integer keys to the storage below it, which is fine for JSON and YAML but may break a storage that can only serialize string keys.
150
+
Without it, that YAML file would open with `'1'`, `'10'`, `'2'`. The trade-off is in the name: the middleware hands integer keys to the storage below it, which is fine for JSON and YAML but may break a storage that can only serialize string keys.
151
151
152
152
### Counting storage operations
153
153
@@ -173,15 +173,17 @@ Event(id=1, name='boot')
173
173
174
174
```
175
175
176
-
The counters are exact where timings are noisy, which makes them the right evidence for a performance bug report — an issue's measurement harness can state "3 storage reads" and be reproducible on any machine. Middlewares stack, and the position in the stack is what gets measured: `ProfilingMiddleware(CachingMiddleware(JSONStorage))` counts only what the cache lets through to disk, while `CachingMiddleware(ProfilingMiddleware(JSONStorage))` counts what the database asks for before caching.
176
+
The counters are exact where timings are noisy, which makes them the right evidence for a performance bug report — an issue's measurement harness can state "3 storage reads" and be reproducible on any machine.
177
+
178
+
Middlewares stack, and the position in the stack is what gets measured. TinyDB talks to the **outermost** wrapper, so `ProfilingMiddleware(CachingMiddleware(JSONStorage))` counts what the database asks for _before_ caching, while `CachingMiddleware(ProfilingMiddleware(JSONStorage))` counts only what the cache lets through to disk. Wrap outermost to answer "how many operations did this call make?", innermost to answer "how much disk traffic did it cause?" — for one insert followed by five `all()` calls, the outer profiler reports 7 reads and 1 write, the inner one 2 reads and 0 writes.
177
179
178
180
## Beyond the built-ins
179
181
180
182
TinyDB's [storage documentation](https://tinydb.readthedocs.io/en/latest/usage.html#storage-types) lists more options, and third-party packages add backends such as SQLite. Any storage that presents the TinyDB `Storage` interface works with `tinydantic` unchanged, because `tinydantic` only ever hands the storage layer JSON-safe primitives.
181
183
182
184
> [!NOTE]
183
185
>
184
-
> `YAMLStorage` and the other helpers under `tinydantic.tinydb` are kept free of any dependency on `tinydantic`'s core, so they can later be extracted into a standalone TinyDB-extensions package. Import them from `tinydantic.tinydb.storages` today; if that extraction happens, the import path is the only thing that would change.
186
+
> `YAMLStorage` and the other helpers under `tinydantic.tinydb` are meant to be extractable into a standalone TinyDB-extensions package, so they depend on `tinydantic`'s core as little as possible. The one dependency today is `ProcessLockMiddleware`, which raises [DatabaseLockedError][tinydantic.DatabaseLockedError] and [TinydanticUserError][tinydantic.TinydanticUserError] from `tinydantic._errors`; an extraction would have to give those errors a home. Everything else — `YAMLStorage`, `SortIntDocIDsMiddleware`, `ProfilingMiddleware`, and the operations — imports nothing from `tinydantic` at all. Import them from `tinydantic.tinydb.storages` and `tinydantic.tinydb.middlewares` today.
0 commit comments