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 TripletStore for RDF triplets and GraphStore for property graphs.
  • Specify backends via constructor: Pass backend="blazegraph" or backend="neo4j" to switch databases instantly.
  • Leverage environment variables: Set GRAPH_STORE_DEFAULT_BACKEND or RDF_STORE_DEFAULT_BACKEND for 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →