Semantic Store¶
The semantic store provides persistence for the Vocabulary pillar: concept schemes, concepts, relationships, and versioned LinkML schema configs. Use it when you need a central registry for business concepts and their relationships, or to store and retrieve LinkML configs by name and version (e.g. for the Vocabulary 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", 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 LinkML schema config
store.store_config("trading_domain", "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_domain", "1.0.0")
store.disconnect()
When to use¶
- Vocabulary workspace — The Web UI uses the semantic store for concept schemes, concepts, relationships, and LinkML schema configs.
- Contract field bindings — Field-level links from contract fields to concepts are stored with 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.
Explicit SQL initialization¶
connect(auto_initialize=True) creates the five managed semantic tables,
including versioned concept-scheme snapshots. It also adds a missing snapshot
table to an existing core-only store. Repeating explicit initialization keeps
stored schemes, snapshots and unrelated tables intact.
Ordinary connect() and reconnect retain their existing validation behavior:
they accept an existing four-table core store and do not implicitly create a
snapshot table. validate_schema_on_connect=False also retains its existing
behavior. Request explicit initialization when adding snapshot storage, or use
the normal database migration workflow. This option creates missing tables;
it does not migrate incompatible columns or change namespace and mutation
policies. Explicit initialization uses the same atomic bootstrap as the other
SQL Stores, including SQLite schema translation and the standard PostgreSQL
pycharter schema. It does not repair custom-schema routing.
SemanticStoreClient¶
Base interface for all semantic stores. Operations are grouped into: concept schemes, concepts, relationships, and LinkML schema configs.
SemanticStoreClient
¶
Bases: VersionedArtifactStore, _ConceptSchemeAbstractMixin, _ConceptAbstractMixin, _RelationshipAbstractMixin, _SchemeDocumentAbstractMixin
Client for the knowledge graph and its versioned LinkML configs.
The versioned-artifact surface (save / get / list /
list_versions / set_status / update / delete,
inherited from :class:VersionedArtifactStore) operates on LinkML
schema configs (the store's one versioned artifact); the
document carries {linkml_yaml, description, scheme_key}. Graph
operations keep explicit names: concepts by name, schemes by
scheme_key, relationships by their own keys. Implementations
extend this for specific backends (PostgreSQL, SQLite, InMemory).
store_scheme
abstractmethod
¶
store_scheme(
scheme_key: str,
version: str,
*,
namespace: str | None = None,
category: str = "domain",
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. |
required |
version
|
str
|
Version string (e.g. |
required |
namespace
|
str | None
|
Identity scope; |
None
|
category
|
str
|
|
'domain'
|
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 |
get_scheme
abstractmethod
¶
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:
| Type | Description |
|---|---|
dict[str, Any] | None
|
Scheme dict or |
list_schemes
abstractmethod
¶
List all concept schemes.
Returns:
| Type | Description |
|---|---|
list[dict[str, Any]]
|
List of scheme summary dicts. |
delete_scheme
abstractmethod
¶
Delete a concept scheme and its concepts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scheme_key
|
str
|
Scheme identifier. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
store_concept
abstractmethod
¶
store_concept(
name: str,
scheme_key: str,
*,
concept_key: str | None = None,
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. |
required |
scheme_key
|
str
|
Parent scheme identifier. |
required |
concept_key
|
str | None
|
Stable cross-artifact identifier; defaults to
|
None
|
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 |
get_concept
abstractmethod
¶
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 |
list_concepts
abstractmethod
¶
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 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 a concept by name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Concept name. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
store_relationship
abstractmethod
¶
store_relationship(
source_name: str,
target_name: str,
relationship_type: str,
*,
author: str | None = None,
scheme_id: str | None = None,
origin: str | None = None,
) -> str
Store a relationship between two concepts.
Implementations must be idempotent: an existing edge with the same source, target, type, and scheme returns its id instead of creating a duplicate.
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. |
required |
author
|
str | None
|
Creator identifier. |
None
|
scheme_id
|
str | None
|
Owning concept scheme id — scheme-scoped graph readers only see edges that carry it. |
None
|
origin
|
str | None
|
Provenance origin (e.g. |
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 a relationship by ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
relationship_id
|
str
|
Relationship identifier. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
list_versions
¶
Return all versions for name, oldest to newest.
get_parsed_schema
¶
Return a parsed LinkMLSchema from the stored YAML.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
schema_name
|
str
|
Ontology identifier. |
required |
schema_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 |
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. |
LinkML schema configurations¶
Versioned LinkML YAML artifacts are stored and retrieved by schema_name and schema_version.
| Method | Description |
|---|---|
store_config(name, version, linkml_yaml, ...) |
Store a LinkML schema config. Optional: description, scheme_key, created_by. |
get_config(name, version) |
Retrieve the full config dict. |
list_configs(name=None) |
List stored configs. |
list_versions(name) |
List versions for a schema. |
update_status(...) |
Update lifecycle status. |
delete_config(name, version) |
Delete a config. |
get_parsed_schema(name, 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¶
- Contract Store — Schema registry; stores field bindings per contract
- Pipeline Store — Pipeline config registry
- Concepts API — Models, parsers, and validators for field bindings and concepts
- Vocabulary guide — Conceptual overview