Semantic queries¶
OntoSession.find() and count() accept semantic field expressions. OntoSQL compiles joins from your OntoMapper — you do not write SQL for nested filters.
Basics¶
# Equality and comparisons
session.find(Person, where=Person.name == "Ada Lovelace")
session.find(Person, where=Person.id > 10)
# String filters
session.find(Person, where=Person.name.startswith("A"))
session.find(Person, where=Person.name.contains("Lovelace"))
session.find(Person, where=Person.name.endswith("ace"))
# Membership and null
session.find(Person, where=Person.id.in_([1, 2, 3]))
session.find(Person, where=Person.employer.is_null())
Nested paths¶
Filter on joined semantic fields via FieldPath:
OntoSQL adds the join from Map.nested on PersonMap.employer.
Boolean combinations¶
session.find(
Person,
where=(Person.name.startswith("A")) & (Person.id > 0),
)
session.find(
Person,
where=(Person.name == "Ada") | (Person.name == "Grace"),
)
Ordering and pagination¶
from ontosql.query import OrderBy
session.find(
Person,
where=Person.name.startswith("A"),
order_by=OrderBy(Person.name, desc=True),
limit=20,
offset=0,
)
from ontosql import paginate
page = paginate(session, Person, where=Person.id > 0, limit=10, offset=0)
print(page.items, page.total)
Count¶
What is not supported¶
- Raw
sqlalchemy.text()inwhere— rejected at compile time (SECURITY) - Arbitrary SQL strings — use SQLAlchemy session directly for ad hoc SQL
- Aggregations (
GROUP BY,SUM) — planned for 0.6 (ROADMAP)
Unsupported expressions raise at compile time, not at runtime.
Async¶
Same API with await:
people = await session.find(Person, where=Person.name.startswith("A"))
page = await paginate_async(session, Person, limit=10)
Related¶
- SPECS.md — operator list
- API reference —
find,count,paginate - Postgres dialect — UUID, JSONB filters