SparqlModel (ORM) + TripleModel (mapping engine)
SparqlModel is a SPARQL ORM. TripleModel is its required mapping engine (triplemodel>=0.12.0,<2 for SparqlModel 0.13+; >=0.10.0 for older releases); in-process graphs use pyoxigraph via triplemodel.Store. This document defines boundaries for contributors and maintainers of both packages.
Architecture (Option A, shipped 0.4.0): SPARQLModel subclasses TripleModel — one class, one mapping path. Session I/O uses rdf_bridge (model_to_graph, load_from_graph) on the same instances. The 0.3 _triple.py adapter was removed in 0.4.
Users: start with ORM.md and the README.
TripleModel’s mirror of this contract:
github.com/eddiethedean/triplemodel/docs/ECOSYSTEM.md
Also: PLAN.md · ROADMAP.md · SPECS.md · PRODUCTION.md · ASYNC_RDF_RUST_PLAN.md (proposed async Rust I/O package)
Choose your package
I need… |
Package |
|---|---|
|
SparqlModel |
|
SparqlModel |
Correct triples, |
TripleModel |
ETL, library, test fixtures without ORM |
TripleModel |
SparqlModel |
TripleModel |
|
|---|---|---|
Metaphor |
SQLModel / SQLAlchemy ORM |
SQLAlchemy Core |
PyPI |
|
|
Imports in apps |
|
Usually transitive; direct for file-only tools |
Stack (required dependency)
Both SparqlModel and TripleModel are Pydantic v2 stacks: validated Python objects in app code, RDF terms in graphs. SparqlModel adds session lifecycle, SPARQL compilation, stores, and cascade policy; TripleModel adds term mapping and file I/O.
┌──────────────────────────────────────────┐
│ SparqlModel │
│ SPARQLModel(TripleModel) · Session · … │
└────────────────────┬─────────────────────┘
│ triplemodel>=0.12.0,<2 (required, 0.13+)
┌────────────────────▼─────────────────────┐
│ TripleModel (Pydantic) │
│ sync_to_graph · from_graph · parse · … │
└────────────────────┬─────────────────────┘
│
┌────────────────────▼─────────────────────┐
│ pyoxigraph · triplemodel · pydantic │
└──────────────────────────────────────────┘
Rules
SparqlModel must depend on
triplemodel>=0.10; must not grow parallel mapping implementations or dynamic shadowTripleModelclasses.TripleModel must not import SparqlModel.
Mapping / literal / format bugs → TripleModel first, then wire SparqlModel.
Session / compiler / cascade bugs → SparqlModel.
SparqlModel owns (ORM)
Area |
Modules |
|---|---|
Session API |
|
Query DSL + SPARQL compiler |
|
Hydration depth |
|
Cascade / orphan policy |
|
Stores |
|
FastAPI (optional extra) |
|
Out of scope: XSD registries, python_to_term, Turtle parsers, stateless parse() without a session.
TripleModel owns (mapping engine)
Area |
Examples |
|---|---|
|
Field metadata |
|
|
Graph I/O |
|
Terms |
Literals, |
Files |
|
SHACL |
|
SPARQLModel is a TripleModel subclass (0.4+); session code calls these APIs on app instances directly.
# TripleModel — no session required
person = Person(slug="alice", name="Alice")
g = person.to_graph()
sync_to_graph(person, g, mode="replace")
restored = Person.from_graph(g, person.subject_uri())
Where to implement a change
Symptom |
Repo |
SparqlModel module |
|---|---|---|
Wrong XSD / datatype |
TripleModel |
— |
Subject IRI safety |
TripleModel |
— |
Stale literal after |
TripleModel |
|
Orphan embedded resource |
SparqlModel |
|
|
SparqlModel |
|
Multi-valued round-trip |
TripleModel (target 1.0) |
|
Language-tagged literals |
TripleModel (target 1.0) |
|
New RDF format |
TripleModel |
thin wrapper in |
Remote Fuseki |
SparqlModel |
|
SHACL validation |
TripleModel |
optional |
Heuristic
If the fix helps code that never uses SPARQLSession, it belongs in TripleModel.
Interim code (retiring)
Module |
Status |
Action |
|---|---|---|
|
Interim adapter (0.3) |
Remove in 0.4 (Option A) |
|
Cascade / orphan policy |
Keep orchestration only |
|
Predicate sugar |
Thin wrapper over |
|
Interim formats |
Thin TripleModel wrappers only (0.7) |
|
Depth walker |
Keep depth; load via |
Do not add new parsers, datatype tables, term converters, or exec-generated shadow model classes to SparqlModel.
Public ORM API vs TripleModel
SparqlModel keeps a stable SQLModel-style surface on a unified base class:
SparqlModel (public) |
TripleModel (implementation) |
|---|---|
|
nested |
|
|
|
|
|
|
|
|
|
|
Dependency pin
# pyproject.toml (SparqlModel)
dependencies = [
"triplemodel>=0.10.0,<2",
"pyoxigraph>=0.5,<0.6",
]
Recommended by TripleModel ecosystem docs for API stability through 1.0.
Optional SparqlModel extras: httpx, fastapi
Optional TripleModel extras (not in SparqlModel core): shacl, sqlalchemy, berkeleydb
Integration milestones
Milestone |
SparqlModel |
TripleModel usage |
|---|---|---|
Done |
|
Package available to all installs |
0.2 |
|
|
0.3 |
Shipped — session I/O via interim adapter |
|
0.4 |
Option A — |
Direct |
0.5 |
Pyoxigraph engine ( |
— |
0.6 |
Async ORM ( |
— |
0.7 |
Thin |
All file |
0.8 |
Query lists ( |
— |
0.9 |
Session cache ( |
— |
1.0 |
Production HttpStore |
Mirror sync, read/write URLs |
1.1 |
Multi-valued / lang / polymorphic query |
TripleModel mapping first |
1.2 |
SHACL hook, bulk, ASK/CONSTRUCT |
|
1.3 |
Production GA (SPECS P0+P1) |
— |
post-1.3 |
Named graphs in apps if needed |
Dataset APIs from TripleModel |
Track upstream: TripleModel ROADMAP · SM-6 (SparqlModel 0.4 unified model)
Testing split
Concern |
Owner |
|---|---|
Literals, parse round-trip, subject URI |
TripleModel |
|
SparqlModel |
Compiler, nested filters |
SparqlModel |
Session CRUD |
SparqlModel |
Cross-package contract |
CI: pinned |
Anti-patterns
Adding
python_to_term(or similar) only in SparqlModelgraph.pyImplementing Turtle/JSON-LD parsers only in SparqlModel
Dynamic shadow
TripleModelclasses viaexec(0.3 adapter — remove in 0.4)Putting
SPARQLSessionor the query compiler in TripleModeltriplemodelimportingsparqlmodelTreating SparqlModel as a second mapping library instead of an ORM on top of TripleModel
Summary
TripleModel |
SparqlModel |
|
|---|---|---|
Role |
Mapping engine |
ORM |
Dependency |
Standalone |
Requires TripleModel |
Killer API |
|
|
Model type |
|
|
New mapping work → TripleModel. New app persistence / SPARQL ergonomics → SparqlModel.