.. _intro_to_using_sparql: ==================== 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 :meth:`rdflib.graph.Graph.query` method, and updates with :meth:`rdflib.graph.Graph.update`. The query method returns a :class:`rdflib.query.Result` instance. For SELECT queries, iterating over this returns :class:`rdflib.query.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... .. code-block:: python 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: .. code-block:: text 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 :doc:`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 :meth:`rdflib.graph.Graph.update` method. An example: .. code-block:: python from rdflib import Graph # Create a Graph, add in some test data g = Graph() g.parse( data=""" a . a . """, format="turtle" ) # Select all the things (s) that are of type (rdf:type) c: qres = g.query("""SELECT ?s WHERE { ?s a }""") for row in qres: print(f"{row.s}") # prints: # x: # y: # Add in a new triple using SPARQL UPDATE g.update("""INSERT DATA { a }""") # Select all the things (s) that are of type (rdf:type) c: qres = g.query("""SELECT ?s WHERE { ?s a }""") print("After update:") for row in qres: print(f"{row.s}") # prints: # x: # y: # z: # Change type of from to g.update(""" DELETE { a } INSERT { a } WHERE { a } """) 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. .. code-block:: python import rdflib g = rdflib.Graph() qres = g.query( """ SELECT ?s WHERE { SERVICE { ?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: .. code-block:: text Prepared Queries ^^^^^^^^^^^^^^^^ RDFLib lets you *prepare* queries before execution, this saves re-parsing and translating the query into SPARQL Algebra each time. The method :meth:`rdflib.plugins.sparql.prepareQuery` takes a query as a string and will return a :class:`rdflib.plugins.sparql.sparql.Query` object. This can then be passed to the :meth:`rdflib.graph.Graph.query` method. The ``initBindings`` kwarg can be used to pass in a ``dict`` of initial bindings: .. code-block:: python 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 :data:`rdflib.plugins.sparql.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 :file:`examples/custom_eval.py`