Semantic metadata reference¶
The complete authoring surface. Two mechanisms: decorator arguments for tables, <column>_<concern> class attributes for fields.
Table level — @semantic_table¶
@semantic_table(
description: str, # required
synonyms: list[str] | None = None,
sql_filters: list[str] | None = None,
application_context: str | None = None,
business_context: str | None = None,
time_dimension: str | None = None,
concept: str | None = None,
)
| Argument | Type | Notes |
|---|---|---|
description |
str |
Required. Put the grain here: "one row per order". |
synonyms |
list[str] |
What users call this entity. ["client", "customer"] |
sql_filters |
list[str] |
Default-filter / RLS fragments. Advisory — not enforced. |
application_context |
str |
Technical or functional scope within the app. |
business_context |
str |
Business domain, and what to know before trusting a number. |
time_dimension |
str |
Column name of the primary business time axis. Validated at sync. |
concept |
str |
(v0.4.0) Id of a registered concept this table realizes. Validated at sync when a registry is passed. |
Each writes to a dunder you can set directly instead:
| Argument | Dunder |
|---|---|
description |
__semantic_description__ |
synonyms |
__semantic_synonyms__ |
sql_filters |
__semantic_sql_filters__ |
application_context |
__semantic_application_context__ |
business_context |
__semantic_business_context__ |
time_dimension |
__semantic_time_dimension__ |
concept |
__semantic_concept__ |
time_dimension on the decorator and __semantic_time_dimension__ on the same class body with different values raises ValueError. A dunder inherited from a mixin or base is overridable by the decorator — so a base can set a default.
Missing decorator → fallback description "Table: <tablename>".
Column level — <column>_<concern>¶
Attributes on the class body, named for the column they annotate.
| Attribute | Type | Notes |
|---|---|---|
<col>_description |
str |
Falls back to "Column: <name>" |
<col>_synonyms |
list[str] |
|
<col>_sample_values |
list[str] |
Representative values. Useless on high-cardinality columns. |
<col>_application_rules |
list[str] |
Constraints an agent must respect. Give expressions, not warnings. |
<col>_privacy_level |
PrivacyLevel |
Advisory — a label, not a control. |
<col>_is_time_dimension |
bool |
Marks a secondary time axis. |
<col>_time_grain |
TimeGrain \| str |
Native resolution — the floor for GROUP BY. |
<col>_concept |
str |
(v0.4.0) Id of a registered concept this column realizes. Validated at sync when a registry is passed. |
class Order(SemanticDeclarativeBase):
total_amount = Column(Numeric(12, 2))
total_amount_description = "Gross order total, including tax and shipping."
total_amount_synonyms = ["order value", "revenue"]
total_amount_application_rules = [
"Do not SUM across the order_lines join — it fans out."
]
Typos are silent
Attributes are read by name. total_ammount_description matches no column and is ignored — no error. See Versioning and CI.
Relationship level¶
| Attribute | Type |
|---|---|
<relationship_attr>_relationship_description |
str |
order_lines = relationship("OrderLine", back_populates="order")
order_lines_relationship_description = (
"One row per line item. Joining here multiplies order rows."
)
Fallback: "Relationship between <from> and <to>".
Enums¶
All in semantido.generators.semantic_layer.
PrivacyLevel¶
PUBLIC · INTERNAL · RESTRICTED · CONFIDENTIAL
TimeGrain¶
SECOND · MINUTE · HOUR · DAY · WEEK · MONTH · QUARTER · YEAR
Ordered — TimeGrain.DAY < TimeGrain.MONTH is True. Accepts case-insensitive strings at authoring time ("day" → TimeGrain.DAY); invalid values raise at sync with the valid list. A grain finer than the column type supports (SECOND on a Date) warns.
RelationshipType¶
ONE_TO_ONE · ONE_TO_MANY · MANY_TO_ONE · MANY_TO_MANY
Extracted automatically. You never author this.
Extracted, never authored¶
| Concern | Source |
|---|---|
| Primary keys | Mapper |
Foreign keys, references (table.column) |
Mapper |
| Relationships, join conditions, cardinality | Mapper |
| Column data types (normalised) | Mapper |
schema |
__table_args__ |
This is the core economy of the design. A join condition typed by hand is a join condition that can be wrong.
Sync-time validation¶
sync_semantic_layer() raises on:
time_dimensionnaming a column not on the tabletime_dimensionnaming a non-Date/DateTimecolumn<col>_time_grainthat isn't a validTimeGraintime_dimensionconflicting with__semantic_time_dimension__on the same class body- (v0.4.0, when a registry is passed) any
concept/<col>_conceptreference not registered — all unresolved references listed in one error
Warns on:
- a declared grain finer than the column type can carry
Silently ignores:
<col>_*attributes matching no column