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.

Production warning: OntoRouter is intended for development and demos only. It has no authentication, no authorization, and does not validate request bodies with Pydantic (POST/PATCH accept raw JSON). Add auth, input validation, and rate limiting before exposing it on a public network. See SPECS.md.

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=94

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.1.tar.gz (52.3 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.1-py3-none-any.whl (36.1 kB view details)

Uploaded Python 3

File details

Details for the file ontosql-0.3.1.tar.gz.

File metadata

  • Download URL: ontosql-0.3.1.tar.gz
  • Upload date:
  • Size: 52.3 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.1.tar.gz
Algorithm Hash digest
SHA256 be6a4d0e95053436499fc9d8f4e7a0d31b564a3a50fd499635e1c156e76c0822
MD5 36d0287ab18b3c22dcf763ee0a097cc5
BLAKE2b-256 04440d6a235117f830005064d065cf821c0880e19a34a5d3004932d984dd45cb

See more details on using hashes here.

File details

Details for the file ontosql-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: ontosql-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 36.1 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6c31e869c59e1b6474b1065347faf70234ed78ad03b196091edf52506ebd1aa6
MD5 2e6df60301a091304d82666b463b685f
BLAKE2b-256 90e500ce3cf63bf35a159061179355b906fae11ce12426956c1721bb0ea9a287

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