Semogram Docs
OntologyConnect the data

Live virtual reads

Read ontology values from existing systems without a materialization run

Virtual reads map ontology terms to fields on a readable endpoint at query time. Use them when records should remain in their source system. The read capability supplies connection behavior; the binding supplies field meaning; the query supplies output shape.

You need a Semogram account with access to the workspace and a project in it. Definition and binding changes, query publication, execution and assertion review require their respective permissions. External reads and writes also require the selected plugin installation's credentials and access.

Prepare a known source

Use a test PostgreSQL database reachable from Semogram's execution runtime. In its SQL client, create the fixture below. These are database instructions, not text to paste into Semogram's endpoint form.

CREATE TABLE public.ontology_demo_orders (
  entity_id text PRIMARY KEY,
  order_id text NOT NULL,
  status text NOT NULL,
  total numeric(12,2) NOT NULL
);
INSERT INTO public.ontology_demo_orders VALUES
  ('https://example.com/orders/1', 'O-001', 'open', 120.00),
  ('https://example.com/orders/2', 'O-002', 'delivered', 75.50);
SELECT * FROM public.ontology_demo_orders ORDER BY entity_id;

Open workspace Plugins → Explore, select Postgres (@craven/postgres) and install its read capability. Enter your database Host, Port (usually 5432), Database, User, Password and Ssl setting. The user needs SELECT access to the fixture. Enter credentials in the protected installation controls and check the connection. More options are explained in the Postgres installation guide.

Create a workspace Data Endpoint named demo_orders, namespace ontology_demo, direction Ingress, using that installed read capability and the source_stream contract. Set target Schema public, Table ontology_demo_orders. Save and inspect the two records. The endpoint name is chosen in Semogram; public.ontology_demo_orders is the physical database table. Keep the returned endpoint UUID. No import or materialization is needed for a live read.

Define the model and bindings

Create the operations-demo definition using the complete model file: namespace https://example.com/operations#, model entrypoint model.ttl, no shapes/imports. Save/validate and inspect its compiled package UUID and numeric version.

Create these Active Virtual bindings in Ontology → Bindings, all selecting the source endpoint and compiled package/version:

Full term IRIApplies toResolutionCardinality
https://example.com/operations#OrderClass{"entity_id_field":"entity_id"}Many
https://example.com/operations#orderIdProperty{"field":"order_id"}One
https://example.com/operations#statusProperty{"field":"status"}One
https://example.com/operations#totalProperty{"field":"total"}One

Use the labeled UI fields or ask the authoring assistant to propose these four bindings and show validation. HTTP callers create each binding with POST /ontology/read-bindings (bindings:write); MCP callers use ontology_read_binding_create with a nested binding object and idempotencyKey. Credentials are never binding resolution fields.

Publish a complete read

In Ontology → Queries, author and validate the complete YAML below after replacing the compiled-package placeholders. Save the draft and publish its exact reviewed version.

query_definition:
  name: Demo orders
  slug: demo-orders
  ontology_package_id: <COMPILED_PACKAGE_UUID>
  ontology_package_version: <COMPILED_PACKAGE_VERSION_NUMBER>
  target:
    kind: virtual
  input_schema:
    type: object
    additionalProperties: false
  root:
    term_ref: https://example.com/operations#Order
    cardinality: many
  output_schema:
    type: object
    properties:
      id: { type: string }
      order_id: { type: string }
      status: { type: string }
      total: { type: number }
    required: [id, order_id, status, total]
  output_mapping:
    id: { term_ref: https://example.com/operations#Order }
    order_id: { term_ref: https://example.com/operations#orderId }
    status: { term_ref: https://example.com/operations#status }
    total: { term_ref: https://example.com/operations#total }

Execute with input: {} and options: {limit: 10}. The UI Execute action, HTTP POST /ontology/queries/<QUERY_UUID>/execute (queries:execute) or MCP query_execute all use a published release. Expect O-001/open/120 and O-002/delivered/75.5, keyed by the source entity IDs. Inspect diagnostics, completeness and source snapshots after the query job completes.

What live means

The source may change between executions. Different sources can be observed at different times; a live read does not promise a distributed transaction. Query result snapshots stabilize continuation within that execution but do not turn an unpinned upstream source into a transactional snapshot.

For mixed-source property reads, use a matching entity identity field on each source. Otherwise one order's status can attach to the wrong order or not attach at all. Check connector field projection, source limits and the emitted ID values before treating a null as a business fact.