Composable semantic views¶
What are composable semantic views?¶
Composable semantic views introduce an IMPORTS clause that lets one semantic view pull in the full
set of tables, dimensions, facts, metrics, and relationships from another semantic view. This creates a
reusable, shared semantic layer where common business definitions are authored once and referenced by
many downstream views.
Without composability, teams that need the same customer, account, or calendar definitions must duplicate them in every semantic view. When definitions drift apart, queries return inconsistent results and maintenance costs increase. Composable semantic views solve this by establishing a single source of truth.
Use cases¶
-
Shared dimensions: Define customer, account, product, geography, or calendar entities in one base semantic view. Domain teams (sales, marketing, finance) import the base view and add their own local facts and metrics.
-
Centralized governance: Business-critical definitions (revenue, churn, active users) are owned by a central analytics team. Downstream consumers import these definitions and can’t accidentally alter them.
-
Modular semantic layers: Large organizations can decompose a monolithic semantic view into focused modules (one per domain) that compose together, reducing complexity and improving change isolation.
-
Cross-domain queries: A composed view that imports both a customer dimension and an orders domain lets users query revenue by customer segment without writing joins or understanding the physical schema.
-
Top-down decomposition: Start with a large, consolidated semantic view and extract focused domain-specific views by selectively importing only the calculations each team needs. This avoids creating separate views from scratch while keeping each domain’s surface area small.
SQL syntax¶
CREATE SEMANTIC VIEW with IMPORTS¶
The IMPORTS clause appears before the TABLES clause. You can import one or more semantic views.
A composed view can also omit TABLES entirely if it only combines imported entities.
Key rules:
- By default, all public calculations from an imported semantic view are brought in,
including their associated entities, relationships, primary keys, unique keys, constraints, synonyms,
comments,
ai_sql_generation,ai_question_categorization, and verified queries. To import only specific calculations, list them by name usingFACTS,DIMENSIONS, orMETRICSsub-clauses inside theIMPORTSclause (see Selective imports). - Imported entity definitions and relationship keys are immutable in the composing view. You can’t rename imported entities or update the join keys of imported relationships.
- Imported entities are referenced by their logical table name and calculation name (for example,
customers.d_regionororders.m_total), the same way you reference local objects. - Relationships between imported entities use logical dimension or fact names, not physical column names.
- A composed view can define local tables alongside imports.
- A composed view can define new metrics on imported entities.
- Any semantic view can be imported as long as the executing role has REFERENCES privilege on it, including cross-schema, cross-database, and shared semantic views.
Selective imports¶
To import only specific calculations from a semantic view, list them by name inside the IMPORTS
clause using FACTS, DIMENSIONS, and METRICS sub-clauses:
If any of FACTS, DIMENSIONS, or METRICS are specified, only those named calculations are
imported. Any sub-clause that is omitted imports nothing for that calculation type. For example,
specifying only FACTS(...) means no dimensions or metrics are imported from that source view.
Entities (tables) and relationships are not listed explicitly. Snowflake automatically imports the minimal subgraph of entities and relationships required to support the imported calculations:
- Each entity that has an imported calculation is included.
- If a path exists between any two included entities in the source view, all entities and relationships along that path are also included.
This means you can query across entities in the composed view without manually redefining the join paths.
:::note
Only the calculations explicitly listed are queryable in the composed view. Dependent
calculations that the imported calculations reference are automatically included as part of
the minimal subgraph, but they aren’t directly queryable unless also listed in the IMPORTS
clause.
:::
Transitive imports¶
Import chains are resolved transitively. If view A imports view B, and view B imports view C, then view A has access to all entities from both B and C:
Transitive imports bring in all public calculations from each view in the chain. The import graph must be acyclic: circular imports cause a creation error.
Runtime behavior¶
A composed view resolves imported objects at query time (late binding). It doesn’t freeze a snapshot of
the source view’s definitions. If the source is altered to remove an object that the composed view
references, the query fails with error 000904 (invalid identifier).
To fix this, restore the missing object in the source view or update the query.
Privilege resolution¶
To create a composed view, the role must have REFERENCES privilege on each directly imported semantic
view, plus SELECT privilege on any new base tables referenced in the composing view’s own TABLES clause.
At query time, imported base tables resolve under the source semantic view’s owner role, not the caller’s role. A user can query a composed view without direct access to the underlying base tables, as long as they have the appropriate privileges on the composed view itself.
YAML format¶
Composable semantic views are supported in YAML. Use the imports top-level block to specify
which semantic views to import:
When a composed view defines a local calc on an imported entity, the exported table entry includes
is_imported: true to mark it as a shadow of the imported entity:
The export also includes an imported_semantic_models block containing the full YAML body of every
semantic view in the transitive import closure.
Diamond imports¶
Diamond import graphs (the same upstream semantic view reachable through multiple paths) are supported. When two imported semantic views both import from the same upstream view, that upstream view’s entities, calculations, and relationships appear exactly once in the composed surface. Snowflake detects the shared source by owning-view identity, not by comparing field values.
Name collisions between two different imported views (not the same upstream source) still cause a creation error. All identifiers across your import graph must be unique.
Metadata and introspection¶
DESCRIBE SEMANTIC VIEW¶
DESCRIBE SEMANTIC VIEW supports a MODE option to control the format of the result:
EXPANDED(default): Returns the fully flattened semantic view metadata across all imports, including all entities and calculations from transitively imported views.COMPACT: Returns only the definitions local to this semantic view, including theIMPORTSclause.
The existing row types are:
- IMPORT rows: One row per directly imported semantic view, with properties
IMPORTED_SEMANTIC_VIEW_DATABASE_NAME,IMPORTED_SEMANTIC_VIEW_SCHEMA_NAME, andIMPORTED_SEMANTIC_VIEW_NAME. - Shadow TABLE rows: Appear when the composed view defines a local calc on an imported entity.
These rows have empty
BASE_TABLE_*values. - Calculations on shadows: Normal METRIC/DIMENSION rows attached to shadow tables.
SHOW SEMANTIC VIEWS¶
The SHOW SEMANTIC VIEWS command includes an imports column that lists direct imports as an array
of fully qualified names. Non-composed views show an empty array ([]).
GET_ DDL¶
GET_DDL output includes the IMPORTS clause with fully qualified semantic view names:
SYSTEM$READ_ YAML_ FROM_ SEMANTIC_ VIEW¶
See YAML format for the full output structure.
Limitations¶
- Snowsight: Snowsight doesn’t support semantic views with imports. Attempting to view or manage a composed semantic view in Snowsight generates an error.
- Replication: Semantic views that use the
IMPORTSclause aren’t replicated. They are skipped during account or database replication. - Variables: Semantic view variables are not supported in composability. Importing a semantic view that defines variables has no effect: the variables are not available in the composing view.
- Composition fails if two imported views define the same logical table alias pointing to different physical tables, or the same calculation name with a different SQL expression.
- When using selective imports, only the named calculations are directly queryable. Their
dependencies are automatically included via the minimal subgraph but aren’t queryable unless
also listed in the
IMPORTSclause.
Example: selective import for top-down decomposition¶
This example starts with a single large semantic view covering three entities and extracts a smaller view by importing only the calculations that a specific team needs.
Example: shared account dimension across domains¶
This end-to-end example creates a shared account dimension and imports it into two domain-specific semantic views (sales and marketing), then runs queries that combine imported and local objects.