How to build a semantic entity from a CoginitiScript block
This guide shows how to point a semantic layer entity at a CoginitiScript block instead of naming a table directly. Use it when a block already builds the dataset you want to expose, and you do not want to repeat the name of the published table in the semantic model.
Semantic layer concepts: Semantic Layer Overview
Semantic model reference: Semantic Model Reference
CoginitiScript publications: CoginitiScript Reference
Prerequisites
- A project with a configured semantic layer
- A CoginitiScript block in the same project, or in a project it depends on
- A database connection that the semantic layer environment points to
How it works
The block publishes a table or a view. The entity reads that published object.
Coginiti reads the publication settings of the block to find the object. Coginiti never runs the block for a semantic query. The entity shows the data of the last publication run, so you keep running the block the way you do today: on a schedule, in a project action, or by hand.
Step 1: Write a block that publishes a table
The block must publish to a table or a view. Give the publication a fixed name.
#+src sql OrdersEnriched()
#+meta {
:publication {
:type "table",
:name "orders_enriched",
:schema "marts"
}
}
#+begin
SELECT
o.order_id,
o.order_date,
o.amount,
c.region
FROM orders o
JOIN customers c ON c.customer_id = o.customer_id
#+end
Run the block once, so the published table exists before you query the entity.
Step 2: Point the entity at the block
In your .smdl file, replace table_name with csl_package and csl_block.
csl_packageis the path of the package that holds the block. It is resolved the same way as a CoginitiScript#+importpath, so you can also name a package of a project dependency.csl_blockis the name of the block in that package.
entity "orders_enriched" {
label = "Enriched Orders"
csl_package = "reporting/blocks"
csl_block = "OrdersEnriched"
dimension "order_id" {
label = "Order ID"
type = "integer"
expr = "order_id"
}
dimension "region" {
label = "Region"
type = "text"
expr = "region"
}
measure "total_amount" {
label = "Total Amount"
type = "number"
aggregation_type = "sum"
expr = "amount"
}
}
Declare the columns you want to use as dimensions and measures, as you do for any other entity.
Step 3: Query the entity
Query the entity like a table-based entity. Relationships to other entities also work.
SELECT
orders_enriched.region,
MEASURE(orders_enriched.total_amount) AS total
FROM orders_enriched
GROUP BY 1
Rules for the block
The block must follow these rules:
- The block is public. A public block name starts with an uppercase letter.
- The block is an
sqlor anllmblock. - The block publishes a table or a view. File publications (
csv,parquet) are not supported. Anllmblock can only publish a table. - The publication
:nameis a plain text value;:schema, if present, is also a plain text value. Expressions and constants are not supported, because Coginiti must know the name of the published object without running the block. - The entity uses
csl_packageandcsl_blocktogether, and does not also usetable_nameorquery.
Troubleshooting
If the reference is not correct, the entity shows an error in the lineage view and queries on that entity fail. The other entities of the model continue to work.
| Message | Cause | What to do |
|---|---|---|
| Package not found | csl_package does not name a package the project can import | Check the path, and check that the project depends on the project that holds the package |
| Block not declared in package | csl_block does not name a block in that package | Check the name of the block |
| Block is not public | The block name starts with a lowercase letter | Rename the block to start with an uppercase letter |
| Block declares no publication | The block has no :publication in its #+meta | Add a table or view publication to the block |
| Block publishes a file | The publication type is csv or parquet | Change the publication to a table or a view |
| LLM block publishes a view | An llm block declares a view publication, which the runtime never creates | Change the publication type to table |
| Publication has a computed name | :name or :schema is an expression or a constant | Replace it with a plain text value |
If the entity resolves but a query returns old data, run the publication again. The semantic layer does not refresh the published table.