Sensemaking AI · Sensemaking Semantic Web
Submodule 4.1 · Shipping

SPARQL UPDATE.

INSERT DATA, DELETE WHERE, CONSTRUCT-into-graph, and the transactional reality of SPARQL Update. Five hands-on update operations — with a data safety mindset throughout.

Module 4 · Weeks 10–12 Capstone module Requires Fuseki UPDATE · INSERT · DELETE · named graphs
Checking for Fuseki at localhost:3030…

SPARQL is not read-only.

SPARQL 1.1 defines a companion language — SPARQL Update — for writing to a graph store. It shares the same PREFIX syntax and the same graph pattern matching as SELECT queries, but the output is mutations to the store rather than a result set. The UPDATE endpoint is separate from the query endpoint by convention (Fuseki uses /update vs /query).

SPARQL Update is the standard way to manage the lifecycle of data in a triplestore: loading initial datasets, adding provenance annotations, correcting errors, materializing inferred triples, retiring outdated assertions. Every production knowledge graph system uses it. The queries in this workbook run against the /update endpoint in the Fuseki UI's "Update" tab.

Use a test dataset — updates are destructive

Unlike SELECT queries, UPDATE operations permanently modify the store. Before running any update in this workbook, either: (a) work in a separate Fuseki dataset you don't mind destroying, or (b) have a backup copy of your TTL file to reload from. The Fuseki UI's "Upload files" function is your restore path. Every update operation below notes what it changes and how to undo it.

What to load

Load modules/02-modeling/artifacts/naruto-ontology/naruto-ontology-starter.ttl into a Fuseki dataset (call it naruto-update or similar — keep it separate from your main dataset). The update lab adds, modifies, and removes data from this dataset. Run each update in the "Update" tab of the Fuseki UI, not the Query tab.

Six operations, two strategies.

SPARQL Update divides into two strategies: explicit (you specify exactly what to add or remove) and pattern-based (the store finds matches and acts on them).

OperationStrategyWhat it does
INSERT DATAExplicitAdds specific, hardcoded triples. No variables. Safest form — no unintended matches possible.
DELETE DATAExplicitRemoves specific, hardcoded triples. If the triple is not present, the operation silently succeeds (no error).
INSERT WHEREPattern-basedAdds triples derived from a WHERE clause match. Powerful — can insert many triples from one operation.
DELETE WHEREPattern-basedFinds and removes triples matching a pattern. Destructive — test the WHERE clause as a SELECT first.
DELETE … INSERT … WHEREPattern-basedReplaces matched triples atomically (at graph level). The standard "update a value" pattern.
CLEAR / DROPExplicitRemoves all triples from a named graph (CLEAR) or removes the graph itself (DROP). Use carefully.
COPY / MOVEExplicitCopies or moves graph contents between named graphs. Useful for version snapshotting.
LOADExplicitLoads an RDF file from a URL into a named graph. Convenient for batch loading.

The DELETE … INSERT … WHERE pattern

The most important compound operation. It atomically replaces the old value of a property with a new value — the SPARQL equivalent of SQL's UPDATE SET WHERE:

# Replace Naruto's rank from Genin to Jonin
PREFIX naruto: <https://sensemaking-ai.com/ns/naruto#>
PREFIX skos:   <http://www.w3.org/2004/02/skos/core#>

DELETE {
  naruto:NarutoUzumaki naruto:hasRank naruto:Genin .
}
INSERT {
  naruto:NarutoUzumaki naruto:hasRank naruto:Jonin .
}
WHERE {
  naruto:NarutoUzumaki naruto:hasRank naruto:Genin .
}

The WHERE clause guards the operation: if Naruto is not currently Genin, neither the DELETE nor the INSERT fires. This is the safe pattern for rank promotions — it will not create a second hasRank triple if one already exists with the new value, because the guard fails if the old value is absent.

Not like SQL — but not without guarantees.

SPARQL Update is not transactional in the SQL sense. The Module 4 README's pain point: "most triplestores offer ACID at graph or statement level, but cross-graph multi-statement transactions are inconsistently supported."

What this means in practice:

# Chain two updates in one request (Fuseki executes both atomically)
PREFIX naruto: <https://sensemaking-ai.com/ns/naruto#>
PREFIX schema: <https://schema.org/>

# First: snapshot the current state
COPY GRAPH naruto:Ontology TO GRAPH naruto:OntologyBackup ;

# Second: add new data
INSERT DATA {
  GRAPH naruto:Ontology {
    naruto:JiraiyaSannin naruto:senseiOf naruto:NarutoUzumaki .
  }
}
Oxigraph vs Fuseki transaction support

Fuseki supports full SPARQL 1.1 Update with Jena's ACID transactions at the dataset level. Oxigraph (the simpler Rust triplestore recommended in Exercise 4.1) offers ACID transactions per operation but has fewer extensions. For the purposes of this curriculum, both behave the same for the operations in this workbook. For production systems handling concurrent writes, check your triplestore's specific transaction documentation before designing the update pattern.

Five operations — paste into the Fuseki Update tab.

These operations run against the Naruto ontology starter data loaded into a test Fuseki dataset. Run them in order — each one builds on the previous state. After each operation, run a SELECT query to verify the change took effect before proceeding.

u01
Add Jiraiya Sannin — a new character not in the starter data.
Pattern: INSERT DATA · explicit triple addition · no WHERE clause needed
Open Update tab ↗
PREFIX rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX schema: <https://schema.org/>
PREFIX naruto: <https://sensemaking-ai.com/ns/naruto#>

INSERT DATA {
  naruto:JiraiyaSannin
      a naruto:Ninja ;
      naruto:canonicalName      "Jiraiya" ;
      schema:name               "Jiraiya"@en , "自来也"@ja ;
      naruto:memberOfVillage    naruto:VillageHiddenLeaf ;
      naruto:hasRank            naruto:Jonin ;
      naruto:senseiOf           naruto:NarutoUzumaki .
}
u02
Promote Naruto from Genin to Jonin — safe rank replacement.
Pattern: DELETE … INSERT … WHERE · guarded replacement · the safe update pattern
Open Update tab ↗
PREFIX naruto: <https://sensemaking-ai.com/ns/naruto#>

# Run this SELECT first to confirm the current state:
# SELECT ?rank WHERE { naruto:NarutoUzumaki naruto:hasRank ?rank . }

DELETE {
  naruto:NarutoUzumaki naruto:hasRank naruto:Genin .
}
INSERT {
  naruto:NarutoUzumaki naruto:hasRank naruto:Jonin .
}
WHERE {
  naruto:NarutoUzumaki naruto:hasRank naruto:Genin .
}
u03
Materialize all studentOf triples by inverting senseiOf — INSERT WHERE.
Pattern: INSERT WHERE · pattern-based bulk insert · materializing inferred data
Open Update tab ↗
PREFIX naruto: <https://sensemaking-ai.com/ns/naruto#>

# INSERT WHERE: for every senseiOf triple,
# add the inverse studentOf triple if it doesn't already exist.
INSERT {
  ?student naruto:studentOf ?sensei .
}
WHERE {
  ?sensei naruto:senseiOf ?student .
  FILTER NOT EXISTS {
    ?student naruto:studentOf ?sensei .
  }
}
u04
Move all Chunin Exams arc data into a named graph for source tracking.
Pattern: INSERT … WHERE with GRAPH target · named graph population from data patterns
Open Update tab ↗
PREFIX schema: <https://schema.org/>
PREFIX naruto: <https://sensemaking-ai.com/ns/naruto#>

# Create a named graph containing only characters
# who appear in the Chunin Exams arc.
INSERT {
  GRAPH naruto:ChunexamsCharacters {
    ?ninja a naruto:Ninja ;
           naruto:canonicalName ?name ;
           naruto:appearsInArc   naruto:ChunexamsArc .
  }
}
WHERE {
  ?ninja a naruto:Ninja ;
         naruto:canonicalName ?name ;
         naruto:appearsInArc   naruto:ChunexamsArc .
}
u05
Snapshot the current graph, then CLEAR and reload — the backup-restore cycle.
Pattern: COPY → CLEAR → LOAD · the safe bulk-update workflow
Open Update tab ↗
PREFIX naruto: <https://sensemaking-ai.com/ns/naruto#>

# Step 1: Snapshot the default graph into a backup named graph
COPY DEFAULT TO GRAPH naruto:SnapshotBeforeBulkUpdate ;

# Step 2: Verify the snapshot exists before proceeding
# (Run separately as a SELECT to check triple count matches)

# Step 3 (run separately after verifying): clear and reload from file
# CLEAR DEFAULT ;
# LOAD <file:///path/to/naruto-ontology-starter.ttl> ;

Reading and next steps.

Primary reading

DuCharme — Ch 5–6

Chapters 5 and 6 cover SPARQL Update and applications. DuCharme's examples are practical and grounded — the closest thing to a cookbook for the patterns in this workbook.

W3C spec

SPARQL 1.1 Update

Section 3 covers the full update language syntax. Section 4 covers the update protocol (HTTP). Bookmark it — you will need it when a compound operation behaves unexpectedly.

Triplestore docs

Apache Jena Fuseki

The Fuseki documentation covers the /update endpoint, the dataset configuration, and transaction semantics specific to Jena's implementation. Read the "SPARQL Update" section before Exercise 4.1.

Next submodule

Submodule 4.2 — Federation and deployment

The SERVICE keyword, federation failure modes, triplestore options, and the EC2 deployment guide for Exercise 4.1. The deployment work feeds directly into the capstone.

Prior data

Naruto ontology starter

The base data file for this workbook's update lab. Load into a separate Fuseki test dataset before running any update operations. Keep the original TTL file as your restore point.

Cheatsheet

Module 4 SPARQL Update quick-reference (coming soon)

All eight update operations, the DELETE … INSERT … WHERE pattern, the backup-restore workflow, and transactional gotchas — one page. Available when Module 4 materials are complete.