Skip to content

Semantic Store

The semantic store provides persistence for the ontology layer: concept schemes, concepts, relationships, and versioned ontology configurations (e.g. LinkML YAML). Use it when you need a central registry for business concepts and their relationships, or to store and retrieve ontology configs by name and version (e.g. for the Ontology workspace in the Web UI).

Overview

from pycharter.semantic_store import PostgresSemanticStore

store = PostgresSemanticStore("postgresql://...")
store.connect()

# Store a concept scheme
store.store_scheme("trading-domain", "1.0.0", title="Trading Domain Ontology", description="...")

# Store concepts within the scheme
store.store_concept("OrderId", "trading-domain", label="Order Identifier", definition="Unique order ID")
store.store_concept("CustomerId", "trading-domain", label="Customer Identifier", broader="PartyId")

# Store a relationship
store.store_relationship("OrderId", "CustomerId", "references")

# Store a versioned ontology config (LinkML YAML)
store.store_config("trading_ontology", "1.0.0", linkml_yaml="...")

# Retrieve
scheme = store.get_scheme("trading-domain")
concepts = store.list_concepts(scheme_key="trading-domain")
config = store.get_config("trading_ontology", "1.0.0")
store.disconnect()

When to use

  • Ontology workspace — The Web UI uses the semantic store for concept schemes, concepts, relationships, and ontology configs.
  • Contract field mapping — Field-level semantic annotations (which concept a field represents) can be stored per contract in the contract store; the semantic store holds the concept definitions and schemes.
  • Governance — Central vocabulary of business terms and their relationships.

Store implementations

Class Backend Use case
InMemorySemanticStore Memory Testing
SQLiteSemanticStore SQLite Development
PostgresSemanticStore PostgreSQL Production, API

Semantic store does not currently implement MongoDB or Redis backends.

SemanticStoreClient

Base interface for all semantic stores. Operations are grouped into: concept schemes, concepts, relationships, and ontology configs.

SemanticStoreClient

SemanticStoreClient(connection_string: str | None = None)

Bases: ABC

Client for storing and retrieving semantic concepts and relationships.

All concept operations are keyed by concept name (unique string). Scheme operations are keyed by scheme_key (unique string). Implementations extend this for specific backends (PostgreSQL, SQLite, InMemory).

Parameters:

Name Type Description Default
connection_string str | None

Database connection string (format depends on implementation).

None

connect abstractmethod

connect() -> None

Establish database connection. Subclasses must implement.

disconnect

disconnect() -> None

Close database connection.

store_scheme abstractmethod

store_scheme(scheme_key: str, version: str, title: str, *, description: str | None = None, base_uri: str | None = None, author: str | None = None) -> str

Store a concept scheme.

Parameters:

Name Type Description Default
scheme_key str

Unique scheme identifier (e.g. "trading-domain").

required
version str

Version string (e.g. "1.0.0").

required
title str

Human-readable title.

required
description str | None

Optional description.

None
base_uri str | None

Optional base URI for concept URIs.

None
author str | None

Optional creator identifier.

None

Returns:

Type Description
str

Scheme ID (implementation-defined).

Raises:

Type Description
ValueError

If scheme_key already exists.

get_scheme abstractmethod

get_scheme(scheme_key: str, version: str | None = None) -> dict[str, Any] | None

Retrieve a concept scheme by key.

Parameters:

Name Type Description Default
scheme_key str

Scheme identifier.

required
version str | None

Optional version filter. If None, returns latest.

None

Returns:

Type Description
dict[str, Any] | None

Scheme dict or None if not found.

list_schemes abstractmethod

list_schemes() -> list[dict[str, Any]]

List all concept schemes.

Returns:

Type Description
list[dict[str, Any]]

List of scheme summary dicts.

delete_scheme abstractmethod

delete_scheme(scheme_key: str) -> bool

Delete a concept scheme and its concepts.

Parameters:

Name Type Description Default
scheme_key str

Scheme identifier.

required

Returns:

Type Description
bool

True if deleted, False if not found.

store_concept abstractmethod

store_concept(name: str, scheme_key: str, *, label: str | None = None, definition: str | None = None, broader: str | None = None, concept_type: str | None = None, tier: str = 'free', uri: str | None = None, notation: str | None = None, deprecated: bool = False, author: str | None = None) -> str

Store a concept within a scheme.

Parameters:

Name Type Description Default
name str

Unique concept name (e.g. "OrderIdentifier").

required
scheme_key str

Parent scheme identifier.

required
label str | None

Human-readable label.

None
definition str | None

Text definition.

None
broader str | None

Name of the parent concept (for hierarchy).

None
concept_type str | None

Concept type (entity, event, etc.).

None
tier str

Governance tier (core, domain, free).

'free'
uri str | None

Full concept URI.

None
notation str | None

Short notation code.

None
deprecated bool

Whether the concept is deprecated.

False
author str | None

Creator identifier.

None

Returns:

Type Description
str

Concept ID (implementation-defined).

Raises:

Type Description
ValueError

If name already exists.

get_concept abstractmethod

get_concept(name: str) -> dict[str, Any] | None

Retrieve a concept by name.

Parameters:

Name Type Description Default
name str

Concept name.

required

Returns:

Type Description
dict[str, Any] | None

Concept dict or None if not found.

list_concepts abstractmethod

list_concepts(scheme_key: str | None = None) -> list[dict[str, Any]]

List concepts, optionally filtered by scheme.

Parameters:

Name Type Description Default
scheme_key str | None

Optional scheme filter.

None

Returns:

Type Description
list[dict[str, Any]]

List of concept dicts.

update_concept abstractmethod

update_concept(name: str, **fields: Any) -> None

Update mutable fields on a concept.

Parameters:

Name Type Description Default
name str

Concept name.

required
**fields Any

Fields to update (label, definition, concept_type, tier, deprecated, etc.).

{}

Raises:

Type Description
ValueError

If the concept does not exist.

delete_concept abstractmethod

delete_concept(name: str) -> bool

Delete a concept by name.

Parameters:

Name Type Description Default
name str

Concept name.

required

Returns:

Type Description
bool

True if deleted, False if not found.

store_relationship abstractmethod

store_relationship(source_name: str, target_name: str, relationship_type: str, *, author: str | None = None) -> str

Store a relationship between two concepts.

Parameters:

Name Type Description Default
source_name str

Source concept name.

required
target_name str

Target concept name.

required
relationship_type str

Relationship type (e.g. "is_a", "depends_on").

required
author str | None

Creator identifier.

None

Returns:

Type Description
str

Relationship ID (implementation-defined).

Raises:

Type Description
ValueError

If source or target concept does not exist.

list_relationships abstractmethod

list_relationships(concept_name: str | None = None, rel_type: str | None = None) -> list[dict[str, Any]]

List relationships, optionally filtered.

Parameters:

Name Type Description Default
concept_name str | None

Filter by source or target concept name.

None
rel_type str | None

Filter by relationship type.

None

Returns:

Type Description
list[dict[str, Any]]

List of relationship dicts.

delete_relationship abstractmethod

delete_relationship(relationship_id: str) -> bool

Delete a relationship by ID.

Parameters:

Name Type Description Default
relationship_id str

Relationship identifier.

required

Returns:

Type Description
bool

True if deleted, False if not found.

store_config abstractmethod

store_config(ontology_name: str, ontology_version: str, linkml_yaml: str, *, description: str | None = None, scheme_key: str | None = None, created_by: str | None = None) -> str

Store a complete ontology configuration (immutable per version).

Parameters:

Name Type Description Default
ontology_name str

Ontology identifier.

required
ontology_version str

Ontology version string.

required
linkml_yaml str

Raw LinkML YAML string (canonical artifact).

required
description str | None

Optional human-readable description.

None
scheme_key str | None

Optional concept scheme reference.

None
created_by str | None

Optional creator identifier.

None

Returns:

Type Description
str

Config ID (implementation-defined).

Raises:

Type Description
ValueError

If (ontology_name, ontology_version) already exists, or if linkml_yaml is invalid.

get_config abstractmethod

get_config(ontology_name: str, ontology_version: str) -> dict[str, Any] | None

Retrieve the full ontology configuration.

Parameters:

Name Type Description Default
ontology_name str

Ontology identifier.

required
ontology_version str

Ontology version string.

required

Returns:

Type Description
dict[str, Any] | None

Dict with keys: ontology_name, ontology_version, linkml_yaml,

dict[str, Any] | None

description, schema_id, scheme_key, status, created_at,

dict[str, Any] | None

created_by. None if not found.

list_configs abstractmethod

list_configs(ontology_name: str | None = None) -> list[dict[str, Any]]

List stored ontology configurations.

Parameters:

Name Type Description Default
ontology_name str | None

Optional filter by ontology name.

None

Returns:

Type Description
list[dict[str, Any]]

List of summary dicts.

list_versions abstractmethod

list_versions(ontology_name: str) -> list[str]

List all stored versions for a given ontology.

Parameters:

Name Type Description Default
ontology_name str

Ontology identifier.

required

Returns:

Type Description
list[str]

Sorted list of version strings.

update_status abstractmethod

update_status(ontology_name: str, ontology_version: str, status: str, *, updated_by: str | None = None) -> None

Update the lifecycle status of a stored config.

Parameters:

Name Type Description Default
ontology_name str

Ontology identifier.

required
ontology_version str

Ontology version string.

required
status str

New status value ("active", "deprecated", "draft").

required
updated_by str | None

Optional updater identifier.

None

Raises:

Type Description
ValueError

If the config does not exist.

delete_config abstractmethod

delete_config(ontology_name: str, ontology_version: str) -> bool

Delete a stored ontology configuration.

Parameters:

Name Type Description Default
ontology_name str

Ontology identifier.

required
ontology_version str

Ontology version string.

required

Returns:

Type Description
bool

True if deleted, False if not found.

get_parsed_schema

get_parsed_schema(ontology_name: str, ontology_version: str) -> LinkMLSchema | None

Return a parsed LinkMLSchema from the stored YAML.

Parameters:

Name Type Description Default
ontology_name str

Ontology identifier.

required
ontology_version str

Ontology version string.

required

Returns:

Type Description
LinkMLSchema | None

Parsed LinkMLSchema, or None if not found.

ingest_vocabulary

ingest_vocabulary(scheme: ConceptScheme, *, author: str = 'seed') -> dict[str, int]

Bulk-load a ConceptScheme into the store.

Two-pass approach: first pass stores all concepts, second pass wires up parent references via update_concept.

Parameters:

Name Type Description Default
scheme ConceptScheme

Parsed concept scheme.

required
author str

Audit trail author string.

'seed'

Returns:

Type Description
dict[str, int]

Dict with created, updated, and total counts.

Concept schemes

Method Description
store_scheme(scheme_key, version, title, ...) Store a concept scheme. Optional: description, base_uri, author.
get_scheme(scheme_key, version=None) Retrieve a scheme; if version is None, returns latest.
list_schemes() List all concept schemes.
delete_scheme(scheme_key) Delete a scheme and its concepts.

Concepts

Method Description
store_concept(name, scheme_key, ...) Store a concept. Optional: label, definition, broader, concept_type, tier, uri, notation, deprecated, author.
get_concept(name) Retrieve a concept by name.
list_concepts(scheme_key=None) List concepts, optionally filtered by scheme.
update_concept(name, **fields) Update mutable fields.
delete_concept(name) Delete a concept.

Relationships

Method Description
store_relationship(source_name, target_name, relationship_type, ...) Store a relationship between two concepts.
list_relationships(concept_name=None, rel_type=None) List relationships with optional filters.
delete_relationship(relationship_id) Delete a relationship by ID.

Ontology configurations

Versioned ontology artifacts (e.g. LinkML YAML) are stored and retrieved by ontology_name and ontology_version:

Method Description
store_config(ontology_name, ontology_version, linkml_yaml, ...) Store an ontology config. Optional: description, scheme_key, created_by.
get_config(ontology_name, ontology_version) Retrieve the full config dict.
list_configs(ontology_name=None) List stored configs.
list_versions(ontology_name) List versions for an ontology.
update_status(...) Update lifecycle status.
delete_config(ontology_name, ontology_version) Delete a config.
get_parsed_schema(ontology_name, ontology_version) Return a parsed LinkMLSchema from the stored YAML.
ingest_vocabulary(scheme, author=...) Bulk-load a ConceptScheme into the store (concepts + hierarchy).

SQLite and Postgres

from pycharter.semantic_store import SQLiteSemanticStore, PostgresSemanticStore

# SQLite (development)
store = SQLiteSemanticStore(connection_string="sqlite:///pycharter.db")
store.connect()

# Postgres (production / API)
store = PostgresSemanticStore(connection_string="postgresql://user:pass@localhost/pycharter")
store.connect()

In-memory

from pycharter.semantic_store import InMemorySemanticStore

store = InMemorySemanticStore()
store.connect()

See also