Semantic data access for SQL — map ontology-shaped models onto real schemas with explicit OntoMapper bindings (import ontosql)
Project description
OntoSQL
Semantic data access for SQL — map ontology-shaped models onto real database schemas and write CRUD in Python, not RDF.
Real databases are not one table per ontology class. OntoSQL separates physical SQLModel tables from semantic Pydantic entities and connects them with an explicit mapper. Application code uses semantic types; OntoSQL compiles SQL on the backend. RDF export uses TripleModel; graph-native apps can pair OntoSQL with SparqlModel — see Ecosystem.
pip install ontosql
pip install "ontosql[fastapi]" # OntoRouter + content negotiation
pip install "ontosql[jsonld]" # optional JSON-LD compact/frame (PyLD)
pip install "ontosql[sparql]" # optional SparqlModel for graph sync / hybrid apps
Quick start
1. Physical models (database truth)
from sqlmodel import Field, SQLModel
class OrgRow(SQLModel, table=True):
__tablename__ = "orgs"
id: int | None = Field(default=None, primary_key=True)
name: str
class PersonRow(SQLModel, table=True):
__tablename__ = "people"
id: int | None = Field(default=None, primary_key=True)
name: str
org_id: int | None = Field(default=None, foreign_key="orgs.id")
2. Semantic models (what your app uses)
from ontosql import OntoModel, onto_property
class Organization(OntoModel):
type_iri = "schema:Organization"
iri_template = "https://data.example.org/org/{id}"
id: int
name: str = onto_property("schema:name")
class Person(OntoModel):
type_iri = "schema:Person"
iri_template = "https://data.example.org/person/{id}"
id: int
name: str = onto_property("schema:name")
employer: Organization | None = onto_property("schema:worksFor")
3. Maps (explicit SQL bindings)
from ontosql import Map, OntoMapper
class OrganizationMap(OntoMapper[Organization]):
entity = Organization
id = Map(OrgRow.id)
name = Map(OrgRow.name, property="schema:name")
class PersonMap(OntoMapper[Person]):
entity = Person
id = Map(PersonRow.id)
name = Map(PersonRow.name, property="schema:name")
employer = Map.nested(
Organization,
join=(PersonRow.org_id == OrgRow.id),
target=OrgRow,
nested_map=OrganizationMap,
property="schema:worksFor",
fk_column=PersonRow.org_id,
)
4. Session (CRUD)
from ontosql import OntoSession, paginate
with OntoSession(engine, maps=[PersonMap, OrganizationMap]) as session:
ada = session.get(Person, id=1)
team = session.find(Person, where=Person.employer.name.startswith("Analytical"))
page = paginate(session, Person, limit=20, offset=0)
new_person = session.save(Person.model_construct(name="Grace Hopper", id=None))
new_person.name = "Grace M. Hopper"
session.save(new_person)
session.delete(new_person)
Async sessions use AsyncOntoSession with the same API (async with, await session.get, await session.find).
5. Export
print(ada.to_rdf(format="turtle"))
print(ada.to_jsonld())
Export walks OntoModel + onto_property metadata and serializes via TripleModel (pyoxigraph). Nested semantic objects become linked RDF resources.
Features
- OntoModel + onto_property — semantic entities with ontology IRIs
- OntoMapper / Map — declarative bindings to columns, joins, and nested entities
- OntoSession / AsyncOntoSession —
get,find,save,delete,paginate, identity map - Semantic queries — nested paths,
contains/endswith,OrderBy(desc=True) - CascadePolicy — explicit nested write behavior on
Map.nested - OntoRouter (
ontosql[fastapi]) — auto CRUD routes + content negotiation - PrefixRegistry — CURIE expansion and JSON-LD
@context(CURIE expand via TripleModel) - Export —
to_jsonld()/to_rdf()on semantic instances (TripleModel serializers) - FastAPI (
ontosql[fastapi]) — content negotiation for JSON-LD and RDF payloads - Ecosystem — TripleModel (core RDF), SparqlModel (optional
ontosql[sparql])
FastAPI
from fastapi import FastAPI
from ontosql.fastapi import OntoRouter, onto_session_lifespan
app = FastAPI()
onto_session_lifespan(app, engine, [PersonMap, OrganizationMap])
router = OntoRouter(maps=[PersonMap, OrganizationMap])
router.register(Person)
router.include_in(app)
See examples/person_org_demo.py for CRUD and examples/person_org_api.py for a runnable API.
Documentation
- Architecture
- Ecosystem — OntoSQL, TripleModel, SparqlModel
- Technical specification
- Roadmap
- Project plan
- Dependency assessment
- Changelog
Development
See Releasing for the version publish checklist.
pip install -e ".[dev]"
ruff check src tests
ruff format src tests
ty check
pytest --cov=ontosql --cov-fail-under=100
License
MIT — see LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ontosql-0.3.0.tar.gz.
File metadata
- Download URL: ontosql-0.3.0.tar.gz
- Upload date:
- Size: 55.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b3eaa1925aa3587ce6481bc2cdcc9e61d5f89d2e51fe4bf3922ba253552489dd
|
|
| MD5 |
6b860b34b9c0b4db32724f4daf8aa87e
|
|
| BLAKE2b-256 |
c1e84ee659ee59b6aea8a59cd7a577c0dbf156d48bef405560a69e555ef9a5da
|
File details
Details for the file ontosql-0.3.0-py3-none-any.whl.
File metadata
- Download URL: ontosql-0.3.0-py3-none-any.whl
- Upload date:
- Size: 35.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
21185d9a37693847e51af31e83bbe4cb4df9acabe14e534609e473e302bb46e2
|
|
| MD5 |
5ca88101238896bb2d35cc95edca7f69
|
|
| BLAKE2b-256 |
caac3cb08f03704c4d2cddd5960eaf09dcf11e38b24bfd28fb204aa6454f5ef0
|