How to Switch Between RDF and LPG Graph Stores in Semantica
Switch between RDF and LPG stores in Semantica by choosing the appropriate facade class—TripletStore** for RDF triplets or GraphStore for labeled property graphs—and specify your backend via the backend parameter or environment variables.**
Semantica provides distinct storage facades for Resource Description Framework (RDF) triple stores and Labeled Property Graph (LPG) databases, allowing you to abstract concrete backends behind a unified API. Whether you need semantic web compatibility via Blazegraph or Jena, or high-performance graph analytics via Neo4j or Apache AGE, the semantica-agi/semantica codebase enables seamless transitions without rewriting your data access logic.
Understanding the Storage Architecture
Semantica separates graph storage into two primary models:
| Model | Primary API | Typical Backends |
|---|---|---|
| RDF (triplet) store | semantica.triplet_store.TripletStore |
Blazegraph, Jena, RDF4J, Anzo, Oxigraph |
| LPG (labeled property graph) store | semantica.graph_store.GraphStore |
Neo4j, Apache AGE, FalkorDB, Amazon Neptune |
Both classes act as facades that hide implementation details behind a single backend constructor argument. This design allows you to swap underlying databases while maintaining identical CRUD operations across your application.
Configuring the RDF Store (TripletStore)
The RDF facade supports multiple backends listed in the class constant SUPPORTED_BACKENDS defined in semantica/triplet_store/triplet_store.py【semantica/triplet_store/triplet_store.py#L48-L55】.
To instantiate an RDF store with a specific backend, pass the backend name and connection parameters:
from semantica.triplet_store import TripletStore
# Default Blazegraph backend
rdf_store = TripletStore(backend="blazegraph", endpoint="http://localhost:9999/blazegraph")
# Switch to Apache Jena
rdf_store = TripletStore(backend="jena", endpoint="http://localhost:3030/ds")
# Switch to RDF4J
rdf_store = TripletStore(backend="rdf4j", endpoint="http://localhost:8080/rdf4j-server")
All operations—including add_triplet(), add_triplets(), and execute_query()—remain consistent regardless of which backend you select.
Configuring the LPG Store (GraphStore)
The LPG facade (GraphStore) reads default configuration from GraphStoreConfig._set_defaults in semantica/graph_store/config.py【semantica/graph_store/config.py#L81-L86】, defaulting to Neo4j if no environment variable is set.
from semantica.graph_store import GraphStore
# Uses default backend from GRAPH_STORE_DEFAULT_BACKEND env var or config (defaults to neo4j)
lpg_store = GraphStore()
# Explicitly specify Neo4j with URI
lpg_store = GraphStore(backend="neo4j", uri="bolt://my-host:7687")
# Use Apache AGE backend
lpg_store = GraphStore(backend="age", host="localhost", port=5432)
Supported LPG backends include "neo4j", "age", "falkordb", and "neptune", each activated through the same backend parameter.
Runtime Switching and Data Migration
Because the two facades are independent, you can maintain concurrent connections and migrate data between paradigms:
# 1. Load from RDF source
rdf_store = TripletStore(backend="blazegraph")
triplets = rdf_store.get_triplets()
# 2. Convert triplets to LPG entities using Semantica helpers
from semantica.utils.helpers import triplets_to_lpg
nodes, relationships = triplets_to_lpg(triplets)
# 3. Persist to LPG store
lpg_store = GraphStore(backend="neo4j", uri="bolt://localhost:7687")
for node in nodes:
lpg_store.create_node(labels=node.labels, properties=node.props)
for rel in relationships:
lpg_store.create_relationship(
rel.start, rel.end, rel.type, rel.props
)
For exporting data back to RDF formats, use the export subsystem:
from semantica.export import RDFExporter, LPGExporter
# Export LPG to Cypher
lpg_exporter = LPGExporter()
lpg_exporter.export(lpg_store, file_path="graph.cypher")
# Export LPG to RDF/Turtle
rdf_exporter = RDFExporter()
rdf_str = rdf_exporter.export_to_rdf(lpg_store, format="turtle")
The conversion utilities are implemented in semantica/utils/helpers.py, while export functionality resides in semantica/export/rdf_exporter.py and semantica/export/lpg_exporter.py.
Environment-Driven Backend Selection
For declarative configuration, set environment variables before launching your application:
export GRAPH_STORE_DEFAULT_BACKEND=age # Switches LPG to Apache AGE
export RDF_STORE_DEFAULT_BACKEND=jena # Switches RDF to Apache Jena
python my_semantica_app.py
When GRAPH_STORE_DEFAULT_BACKEND is set, GraphStore() initializes without requiring an explicit backend argument:
from semantica.graph_store import GraphStore
store = GraphStore() # Automatically uses Apache AGE from environment
Summary
- Choose the correct facade: Use
TripletStorefor RDF triplets andGraphStorefor property graphs. - Specify backends via constructor: Pass
backend="blazegraph"orbackend="neo4j"to switch databases instantly. - Leverage environment variables: Set
GRAPH_STORE_DEFAULT_BACKENDorRDF_STORE_DEFAULT_BACKENDfor configuration-free initialization. - Migrate data at runtime: Use
triplets_to_lpg()helpers and export classes to convert between storage models without data loss. - Consistent API: All CRUD methods remain identical across backends, ensuring your application logic stays portable.
Frequently Asked Questions
Can I use both RDF and LPG stores in the same application?
Yes. The TripletStore and GraphStore classes operate independently, allowing you to instantiate both simultaneously. You can read from an RDF backend using semantica.triplet_store.TripletStore, transform the data using semantica.utils.helpers.triplets_to_lpg(), and write to an LPG backend via semantica.graph_store.GraphStore in a single script.
How do I check which backends are supported by my Semantica installation?
For RDF stores, inspect the SUPPORTED_BACKENDS class attribute in semantica/triplet_store/triplet_store.py. For LPG stores, check the GraphStoreConfig class in semantica/graph_store/config.py, which defines available backends and their default connection parameters.
What is the default backend if I do not specify one?
GraphStore defaults to Neo4j ("neo4j") as defined in GraphStoreConfig._set_defaults unless overridden by the GRAPH_STORE_DEFAULT_BACKEND environment variable. TripletStore typically defaults to Blazegraph if no backend argument is provided, though this depends on your specific Semantica version configuration.
Can I switch backends without restarting my Python process?
Yes. Since the backend selection occurs at instantiation time, you can create new store instances with different backends while the process runs. However, existing store objects maintain their original backend connections. To switch an active connection, instantiate a new TripletStore or GraphStore with the desired backend parameter and migrate data as needed using the export and conversion utilities.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →