Using SPARQL to query an rdflib 3 graph

Get the SPARQL RDFLib plugin

SPARQL is no longer shipped with core RDFLib, instead it is now a part of rdfextras

Assuming you have rdfextras installed with setuptools (highly recommended), you can use SPARQL with RDFLib 3.X out of the box.

If you only have distutils, you have to add these lines somewhere at the top of your program:

import rdfextras
rdfextras.registerplugins()

Create an RDFLib Graph

You might parse some files into a new graph or open an on-disk RDFLib store.

from rdflib.graph import Graph
g = Graph()
g.parse("http://www.w3.org/People/Berners-Lee/card.rdf")

Run a Query

querystr = """
SELECT ?aname ?bname
WHERE {
    ?a foaf:knows ?b .
    ?a foaf:name ?aname .
    ?b foaf:name ?bname .
}"""
for row in g.query(
    querystr,
    initNs=dict(foaf=Namespace("http://xmlns.com/foaf/0.1/"))):

    print("%s knows %s" % row)

The results are tuples of values in the same order as your SELECT arguments.

Timothy Berners-Lee knows Edd Dumbill
Timothy Berners-Lee knows Jennifer Golbeck
Timothy Berners-Lee knows Nicholas Gibbins
Timothy Berners-Lee knows Nigel Shadbolt
Dan Brickley knows binzac
Timothy Berners-Lee knows Eric Miller
Drew Perttula knows David McClosky
Timothy Berners-Lee knows Dan Connolly
...

Namespaces

The rdfextras.sparql.graph.Graph.parse() initNs argument is a dictionary of namespaces to be expanded in the query string. In a large program, it’s common to use the same dict for every single query. You might even hack your graph instance so that the initNs arg is already filled in.

If someone knows how to use the empty prefix (e.g. ”?a :knows ?b”), please write about it here and in the Graph.query docs.

Bindings

As with conventional SQL queries, it’s common to run the same query many times with only a few terms changing. rdflib calls this initBindings:

FOAF = Namespace("http://xmlns.com/foaf/0.1/")
ns = dict(foaf=FOAF)
drew = URIRef('http://bigasterisk.com/foaf.rdf#drewp')
for row in g.query('SELECT ?name WHERE { ?p foaf:name ?name }',
                   initNs=ns,
                   initBindings={'p' : drew}):
    print(row)

Output:

(rdflib.Literal('Drew Perttula', language=None, datatype=None),)

See also the the rdflib.graph.Graph.query() API docs