Skip to main content

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 / AsyncOntoSessionget, 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)
  • Exportto_jsonld() / to_rdf() on semantic instances (TripleModel serializers)
  • FastAPI (ontosql[fastapi]) — content negotiation for JSON-LD and RDF payloads
  • EcosystemTripleModel (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

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

ontosql-0.3.0.tar.gz (55.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ontosql-0.3.0-py3-none-any.whl (35.7 kB view details)

Uploaded Python 3

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

Hashes for ontosql-0.3.0.tar.gz
Algorithm Hash digest
SHA256 b3eaa1925aa3587ce6481bc2cdcc9e61d5f89d2e51fe4bf3922ba253552489dd
MD5 6b860b34b9c0b4db32724f4daf8aa87e
BLAKE2b-256 c1e84ee659ee59b6aea8a59cd7a577c0dbf156d48bef405560a69e555ef9a5da

See more details on using hashes here.

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

Hashes for ontosql-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 21185d9a37693847e51af31e83bbe4cb4df9acabe14e534609e473e302bb46e2
MD5 5ca88101238896bb2d35cc95edca7f69
BLAKE2b-256 caac3cb08f03704c4d2cddd5960eaf09dcf11e38b24bfd28fb204aa6454f5ef0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page