Skip to content

# Querying with SPARQL

## Run a Query

The RDFLib comes with an implementation of the SPARQL 1.1 Query and SPARQL 1.1 Update query languages.

Queries can be evaluated against a graph with the `query()` method, and updates with `update()`.

The query method returns a `Result` instance. For SELECT queries, iterating over this returns `ResultRow` instances, each containing a set of variable bindings. For `CONSTRUCT`/`DESCRIBE` queries, iterating over the result object gives the triples. For `ASK` queries, iterating will yield the single boolean answer, or evaluating the result object in a boolean-context (i.e. `bool(result)`)

For example…

    import rdflib
    g = rdflib.Graph()
    g.parse("http://danbri.org/foaf.rdf#")

    knows_query = """
    SELECT DISTINCT ?aname ?bname
    WHERE {
        ?a foaf:knows ?b .
        ?a foaf:name ?aname .
        ?b foaf:name ?bname .
    }"""

    qres = g.query(knows_query)
    for row in qres:
        print(f"{row.aname} knows {row.bname}")

The results are tuples of values in the same order as your `SELECT` arguments. Alternatively, the values can be accessed by variable name, either as attributes, or as items, e.g. `row.b` and `row["b"]` are equivalent. The above, given the appropriate data, would print something like:

    Timothy Berners-Lee knows Edd Dumbill
    Timothy Berners-Lee knows Jennifer Golbeck
    Timothy Berners-Lee knows Nicholas Gibbins
    ...

As an alternative to using `SPARQL`’s `PREFIX`, namespace bindings can be passed in with the `initNs` kwarg, see namespaces_and_bindings.

Variables can also be pre-bound, using the `initBindings` kwarg which can pass in a `dict` of initial bindings. This is particularly useful for prepared queries, as described below.

## Update Queries

Update queries are performed just like reading queries but using the `update()` method. An example:

    from rdflib import Graph

    # Create a Graph, add in some test data
    g = Graph()
    g.parse(
        data="""
            <x:> a <c:> .
            <y:> a <c:> .
        """,
        format="turtle"
    )

    # Select all the things (s) that are of type (rdf:type) c:
    qres = g.query("""SELECT ?s WHERE { ?s a <c:> }""")

    for row in qres:
        print(f"{row.s}")
    # prints:
    # x:
    # y:

    # Add in a new triple using SPARQL UPDATE
    g.update("""INSERT DATA { <z:> a <c:> }""")

    # Select all the things (s) that are of type (rdf:type) c:
    qres = g.query("""SELECT ?s WHERE { ?s a <c:> }""")

    print("After update:")
    for row in qres:
        print(f"{row.s}")
    # prints:
    # x:
    # y:
    # z:

    # Change type of <y:> from <c:> to <d:>
    g.update("""
             DELETE { <y:> a <c:> }
             INSERT { <y:> a <d:> }
             WHERE { <y:> a <c:> }
             """)
    print("After second update:")
    qres = g.query("""SELECT ?s ?o WHERE { ?s a ?o }""")
    for row in qres:
        print(f"{row.s} a {row.o}")
    # prints:
    # x: a c:
    # z: a c:
    # y: a d:

## Querying a Remote Service

The `SERVICE` keyword of SPARQL 1.1 can send a query to a remote SPARQL endpoint.

    import rdflib

    g = rdflib.Graph()
    qres = g.query(
        """
        SELECT ?s
        WHERE {
          SERVICE <https://dbpedia.org/sparql> {
            ?s a ?o .
          }
        }
        LIMIT 3
        """
    )

    for row in qres:
        print(row.s)

This example sends a query to DBPedia’s SPARQL endpoint service so that it can run the query and then send back the result:

    <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.openlinksw.com/schemas/virtcxml#FacetCategoryPattern>
    <http://www.w3.org/2001/XMLSchema#anyURI> <http://www.w3.org/2000/01/rdf-schema#Datatype>
    <http://www.w3.org/2001/XMLSchema#anyURI> <http://www.w3.org/2000/01/rdf-schema#Datatype>

## Prepared Queries

RDFLib lets you prepare queries before execution, this saves re-parsing and translating the query into SPARQL Algebra each time.

The method `prepareQuery()` takes a query as a string and will return a `Query` object. This can then be passed to the `query()` method.

The `initBindings` kwarg can be used to pass in a `dict` of initial bindings:

    q = prepareQuery(
        "SELECT ?s WHERE { ?person foaf:knows ?s .}",
        initNs = { "foaf": FOAF }
    )

    g = rdflib.Graph()
    g.parse("foaf.rdf")

    tim = rdflib.URIRef("http://www.w3.org/People/Berners-Lee/card#i")

    for row in g.query(q, initBindings={'person': tim}):
        print(row)

## Custom Evaluation Functions

For experts, it is possible to override how bits of SPARQL algebra are evaluated. By using the setuptools entry-point `rdf.plugins.sparqleval`, or simply adding to an entry to `CUSTOM_EVALS`, a custom function can be registered. The function will be called for each algebra component and may raise `NotImplementedError` to indicate that this part should be handled by the default implementation.

See `examples/custom_eval.py`