synology_apm_repo.sdk.storage.table module¶
Schema-tolerant SQLite table access — declare the columns
a query needs and whether each is required, and this introspects the real
table once (PRAGMA table_info) to work out which optional columns
this particular connector version’s schema actually has. A missing
optional column reads back as None for every row instead of raising
sqlite3.OperationalError: no such column — the failure mode this
project hits repeatedly across every workload DB, not just those two.
- class synology_apm_repo.sdk.storage.table.Column(name, required=True)¶
Bases:
objectOne column a
Tableexpects —required=Falsefor a column only some connector-version schemas have.
- class synology_apm_repo.sdk.storage.table.Table(name, columns)¶
Bases:
objectA schema-tolerant view of one real SQLite table.
Introspects
PRAGMA table_info(name)once at construction time — cheap, and the schema can’t change under a read-only connection midTablelifetime. RaisesDataCorruptErrorimmediately if any required column is absent; missing optional columns are simply left out of theSELECTand backfilled asNonein every row.Constructed via
await Table.create(conn, name, columns), neverTable(conn, ...)directly: introspectingPRAGMA table_infois a database query, and__init__cannot beasync def— the same async-classmethod-factory idiomaiosqlite.connect()uses.- async classmethod create(conn, name, columns, *, index_hints=())¶
Introspect
name’s real schema and return aTablebound toconn.index_hints: each entry is a column-name sequence this table’s callers intend to filter/sort by (e.g.[["parent_folder_id"]], or a composite), declared here alongside the schema introspection rather than scattered into query logic later. Each is passed straight toapply_index_hint, which doesn’t need to know or care whetherconnallows writing.
- async static exists_in(conn, name)¶
Whether
nameexists at all (and has at least one column) — a non-raising presence check, for the genuinely different situation from a missing column: some repository shapes don’t have a given table at all (e.g.file_metamay not exist in every repository shape). Callers needing that distinction check this before constructing aTable— the constructor’s own “table must exist” contract stays intact for the normal “table exists but drifted a column” case.
- property columns_present: frozenset[str]¶
The table’s actual full column set, as introspected — independent of which columns this
Tablewas asked to declare. For call sites that must pick a real column name via a heuristic rather than a fixed declaration, because the table’s schema varies across repositories and so there is no fixed name to declare.
- async select(where='', params=(), *, order_by=None, limit=None, offset=0)¶
Run
SELECT <present columns> FROM <name> [WHERE <where>] [ORDER BY <order_by>] [LIMIT ? OFFSET ?]and yield each row as{column_name: value}, with every declared-but-absent optional column backfilled asNone.where/order_byare literal SQL fragments written by the caller (not untrusted input) — parameterize actual values viaparams; this only ever interpolates column/table names this module itself introspected.limit/offsetare the pagination primitives:limit=None(default) means “no cap” but still letsoffsetapply via SQLite’s ownLIMIT -1idiom, sinceOFFSETalone isn’t valid syntax without someLIMITpresent. Both are parameterized (?), since they’re plain integers from the caller, not schema-derived text.
- async select_one(where='', params=())¶
- synology_apm_repo.sdk.storage.table.as_int(value)¶
Narrow one of
Table.select’sobject | Nonevalues toint— a thin, explicit boundary between a caller’s typed dataclasses and the untypeddictrows SQLite hands back, rather than scattering# type: ignoreat every call site. RaisesDataCorruptError, the same exception this module’s ownTable.createalready raises for a schema mismatch, rather than a bareAssertionErrora caller’sexcept (..., DataCorruptError, ...)degrade path wouldn’t catch.
- synology_apm_repo.sdk.storage.table.as_str(value)¶
Narrow one of
Table.select’sobject | Nonevalues tostr, the same wayas_intnarrows toint.
- synology_apm_repo.sdk.storage.table.sql_placeholders(n)¶
A comma-joined
n-item"?"placeholder list for a batchedWHERE <column> IN (...)query — every caller building one of these still owns its own “nothing to look up” early return (an emptyIN ()is invalid SQL), just not the placeholder string itself.