httk.store.backend.sql.mapping
==============================
.. py:module:: httk.store.backend.sql.mapping
.. autoapi-nested-parse::
Schema-to-SQL mapping: build SQLAlchemy Core tables from resolved :class:`~httk.store.backend.schema.TableSchema` IR.
:func:`table_for` turns one resolved schema into a :class:`sqlalchemy.Table`
registered in a :class:`sqlalchemy.MetaData` (idempotently: an already-built
table is returned as-is), recursing into referenced and child-element storable
classes so that the complete logical layout is present in the same metadata.
:func:`sqlalchemy_metadata` is the convenience wrapper that maps a batch of
schemas into one fresh metadata.
The relational layout produced here is exactly the one the schema IR
documents, plus the store-managed columns:
- every parent table gets an ``sid`` integer primary key (autoincrementing,
with an attached ``
_sid_seq`` sequence for dialects such as DuckDB
that need one; SQLite ignores it) and — only under the ``"content_id"``
dedup policy — a unique-indexed ``content_id`` text column;
- every child table gets a ``_sid`` integer sid column (NOT NULL,
indexed) and a ``_index`` integer ordering column ahead of its element
columns; logical references are defined by :mod:`httk.store.backend.sql.graph`.
Index names are deterministic and table-scoped — ``ix__`` for
plain indexes, ``uq__`` for unique ones, columns joined by
underscores for composites — truncated with a stable hash suffix when they
would exceed common identifier-length limits.
Attributes
----------
.. autoapisummary::
httk.store.backend.sql.mapping.SID_COLUMN
httk.store.backend.sql.mapping.CONTENT_ID_COLUMN
httk.store.backend.sql.mapping.ROLE_COLUMN
httk.store.backend.sql.mapping.STORE_TIMESTAMP_COLUMN
httk.store.backend.sql.mapping.LOGICAL_ID_COLUMN
httk.store.backend.sql.mapping.ALT_ID_COLUMN
httk.store.backend.sql.mapping.ALT_KIND_COLUMN
httk.store.backend.sql.mapping.DISPATCH_CONTENT_ID_COLUMN
httk.store.backend.sql.mapping.SOURCE_LID_COLUMN
httk.store.backend.sql.mapping.TARGET_LID_COLUMN
httk.store.backend.sql.mapping.RETRACTED_COLUMN
httk.store.backend.sql.mapping.ENTRY_ID_OWNERS_TABLE_NAME
httk.store.backend.sql.mapping.IMMUTABLE_ID_OWNERS_TABLE_NAME
Functions
---------
.. autoapisummary::
httk.store.backend.sql.mapping.sqlalchemy_metadata
httk.store.backend.sql.mapping.entry_dispatch_table_name
httk.store.backend.sql.mapping.backing_dispatch_column_name
httk.store.backend.sql.mapping.dispatch_table_for
httk.store.backend.sql.mapping.identity_owner_tables
httk.store.backend.sql.mapping.table_for
httk.store.backend.sql.mapping.link_table_for
httk.store.backend.sql.mapping.added_column_ddl
Module Contents
---------------
.. py:data:: SID_COLUMN
:type: Final
:value: 'sid'
The store-managed integer primary-key column present on every table.
.. py:data:: CONTENT_ID_COLUMN
:type: Final
:value: 'content_id'
The store-managed content-identity column of tables with the ``"content_id"`` dedup policy.
.. py:data:: ROLE_COLUMN
:type: Final
:value: '_httk_role'
The permanentization role of a parent record — ``0`` dependency, ``1`` main.
.. py:data:: STORE_TIMESTAMP_COLUMN
:type: Final
:value: 'store_timestamp'
The store-managed integer timestamp on every parent record table.
.. py:data:: LOGICAL_ID_COLUMN
:type: Final
:value: 'logical_id'
The store-managed lineage identity on every parent record table (a fresh record's own sid, copied by a replacement).
.. py:data:: ALT_ID_COLUMN
:type: Final
:value: 'alt_id'
The store-managed alternative-group identity on every parent record table (a main's ``logical_id``; self for mains).
.. py:data:: ALT_KIND_COLUMN
:type: Final
:value: 'alt_kind'
The store-managed alternative kind on every parent record table (``NULL`` for mains, a kind name for alternatives).
.. py:data:: DISPATCH_CONTENT_ID_COLUMN
:type: Final
:value: 'content_id'
The content identity primary key of an entry-family dispatch table.
.. py:data:: SOURCE_LID_COLUMN
:type: Final
:value: 'source_lid'
The source lineage id (a source record's ``logical_id``) of a weak-link row.
.. py:data:: TARGET_LID_COLUMN
:type: Final
:value: 'target_lid'
The target lineage id (a target record's ``logical_id``) of a weak-link row.
.. py:data:: RETRACTED_COLUMN
:type: Final
:value: 'retracted'
Whether a weak-link revision retracts the pair (``1``) or asserts it (``0``).
.. py:data:: ENTRY_ID_OWNERS_TABLE_NAME
:type: Final
:value: '_httk_entry_id_owners'
.. py:data:: IMMUTABLE_ID_OWNERS_TABLE_NAME
:type: Final
:value: '_httk_immutable_id_owners'
.. py:function:: sqlalchemy_metadata(schemas, *, store_timestamps = True)
A fresh :class:`sqlalchemy.MetaData` holding the tables of ``schemas`` (recursively).
.. py:function:: entry_dispatch_table_name(family_name)
The deterministic reserved table name for one registered entry family.
.. py:function:: backing_dispatch_column_name(backing_name)
The deterministic nullable foreign-key column for one backing in a dispatch table.
.. py:function:: dispatch_table_for(family_name, backings, metadata)
Build the one-of-many dispatch table for an entry family.
A single-backing family has no dispatch table and must not call this
helper. The primary key is the backing record's canonical content id;
every nullable backing sid is unique on its own, and the named check
constraint makes precisely one of them non-null.
.. py:function:: identity_owner_tables(metadata)
Build the two family-wide entry-identity ownership tables.
.. py:function:: table_for(schema, metadata, *, store_timestamps = True)
The :class:`sqlalchemy.Table` of ``schema`` within ``metadata``, building it on first use.
Building is idempotent per metadata — if the table is already registered it
is returned unchanged — and recursive: the child tables of the schema and
the tables of every referenced storable class (reference fields and
storable child elements alike) are built into the same metadata, so the
complete logical layout is available to the storage algorithms.
.. py:function:: link_table_for(link, metadata, *, store_timestamps = True)
The append-only link table backing one weak-link declaration, built on first use.
Columns: an autoincrement ``sid`` primary key, a non-unique-indexed
``logical_id`` lineage column (a fresh row's own sid, copied by a revision),
an optional ``store_timestamp`` (present exactly when the store keeps
timestamps), the ``source_lid``/``target_lid`` endpoint lineage ids, and a
``retracted`` flag. Indexes cover ``(source_lid, target_lid)`` and
``(target_lid)``.
.. py:function:: added_column_ddl(table_name, spec, connection)
The DDL statements adding one nullable column (and its declared index) to an existing table.
The column type and the deterministic index name reuse the same mappings
:func:`table_for` builds tables with, so an additively upgraded table is
physically identical to one that lazy DDL would build from scratch.
:param table_name: The existing parent table being altered.
:param spec: The nullable column to add (an additive upgrade only adds nullable columns).
:param connection: The live connection whose dialect renders types and quotes identifiers.
:return: One ``ALTER TABLE ... ADD COLUMN`` statement, plus an idempotent
``CREATE INDEX IF NOT EXISTS`` statement when the column declares an index.