Example 2: Asserting and retracting triples¶
In this example we show how to create resources describing two people,
Bob and Alice, by asserting triples into the repository. The example
also retracts and replaces a triple. Assertions and retractions to the
triple store are executed by add()
and remove()
methods
belonging to the connection object, which we obtain by calling the
ag_connect()
function described in Example 1: Creating a repository and triple indices.
Before asserting a triple, we have to generate the URI values for the
subject, predicate and object fields. The AllegroGraph Python client
API predefines a number of classes and predicates for the RDF, RDFS,
XSD, and OWL ontologies. RDF.TYPE
is one of the predefined
predicates we will use.
The add()
and remove()
methods take an optional
contexts
argument that specifies one or more subgraphs that are
the target of triple assertions and retractions. When the context is
omitted, triples are asserted/retracted to/from the default graph. In
the example below, facts about Alice and Bob reside in the default
graph.
The second example begins by calling ag_connect()
to create the
appropriate connection object, which is bound to the variable conn
.
from franz.openrdf.connect import ag_connect
conn = ag_connect('python-tutorial', create=True, clear=True)
The next step is to begin assembling the URIs we will need for the new
triples. The createURI()
method generates a URI from a string.
These are the subject URIs identifying the resources “Bob” and “Alice”:
alice = conn.createURI("http://example.org/people/alice")
bob = conn.createURI("http://example.org/people/bob")
Bob and Alice will be members of the “person” class (rdf type
person
).
person = conn.createURI("http://example.org/ontology/Person")
Both Bob and Alice will have a “name” attribute.
name = conn.createURI("http://example.org/ontology/name")
The name attributes will contain literal values. We have to generate the
Literal
objects from strings:
bobsName = conn.createLiteral("Bob")
alicesName = conn.createLiteral("Alice")
The next line prints out the number of triples currently in the
repository - we expect that to be zero, since we have not yet added
any triples and the connect
function should have removed any
existing statements from the repository.
print("Triple count before inserts:", conn.size())
Triple count before inserts: 0
Now we assert four triples, two for Bob and two more for Alice, using
the connection object’s add()
method. After
the assertions, we count triples again (there should be four) and print
out the triples for inspection.
from franz.openrdf.vocabulary import RDF
# alice is a person
conn.add(alice, RDF.TYPE, person)
# alice's name is "Alice"
conn.add(alice, name, alicesName)
# bob is a person
conn.add(bob, RDF.TYPE, person)
# bob's name is "Bob":
conn.add(bob, name, bobsName)
print("Triple count:", conn.size())
for s in conn.getStatements(None, None, None, None):
print(s)
The None
arguments to the getStatements()
method say that we
don’t want to restrict what values may be present in the subject, predicate,
object or context positions. Just print out all the triples.
This is the output at this point. We see four triples, two about Alice and two about Bob
Triple count: 4
(<http://example.org/people/alice>, <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>, <http://example.org/ontology/Person>)
(<http://example.org/people/alice>, <http://example.org/ontology/name>, "Alice")
(<http://example.org/people/bob>, <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>, <http://example.org/ontology/Person>)
(<http://example.org/people/bob>, <http://example.org/ontology/name>, "Bob")
We see two resources of type “person,” each with a literal name.
The next step is to demonstrate how to remove a triple. Use the
remove()
method of the connection object, and supply a triple pattern
that matches the target triple. In this case we want to remove Bob’s name
triple from the repository. Then we’ll count the triples again to verify
that there are only three remaining.
conn.remove(bob, name, bobsName)
print("Triple count:", conn.size())
Triple count: 3
A potentially less verbose way of adding triples is to use the
addData()
method of the connection object with a string
containing triples in Turtle, N-Triples or another RDF format.
Let us see how the data used in this example could be added using
addData()
. We will also wrap the whole process in a function
that we’ll use later:
def add_bob_and_alice(conn):
conn.addData("""
@base <http://example.org/> .
<people/alice> a <ontology/Person> ;
<ontology/name> "Alice" .
<people/bob> a <ontology/Person> ;
<ontology/name> "Bob" .
""")
The string used here is in the Turtle format. It is also possible
to use other formats by passing the rdf_format
argument to
addData()
.
We should check if the new function behaves as expected by creating a
fresh connection (recall that the clear
parameter causes all existing
triples to be deleted):
with ag_connect('python-tutorial', clear=True) as conn:
add_bob_and_alice(conn)
print("Triple count:", conn.size())
Triple count: 4