Skip to content

Commit 897e9d0

Browse files
committed
docs: add docs section on SPARQL result conversion
1 parent f9997ba commit 897e9d0

1 file changed

Lines changed: 75 additions & 1 deletion

File tree

docs/rdflib_integration.md

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,81 @@
11
# RDFLib Integration
22

33
## SPARQL Result Conversion
4-
[todo]
4+
5+
As mentioned in the [README](../README.md), `SPARQLWrapper` query methods feature a `convert: bool` flag for conversion of SPARQL responses to Python result representations.
6+
7+
E.g. if the `convert` parameter is set to `True`, `SPARQLWrapper.query` returns
8+
9+
- a `list` of Python dictionaries with dict-values cast to RDFLib objects for `SELECT` queries
10+
- a Python `bool` for `ASK` queries
11+
- an `rdflib.Graph` instance for `CONSTRUCT` and `DESCRIBE` queries.
12+
13+
Not that currently only JSON is supported as a response format for `convert=True` on `SELECT` and `ASK` query results.
14+
15+
16+
### JSON Response Conversion of SELECT Query Results
17+
18+
While for graph result conversion (`CONSTRUCT` and `DESCRIBE` queries), the requested `response_format` is simply passed to `rdflib.Graph.parse` along with the response content,
19+
the `SELECT` query converter logic in `sparqlx` processes response JSON adhering to the [SPARQL 1.2 Query Results JSON Format](https://www.w3.org/TR/sparql12-results-json/) and generates a Python mapping with RDFLib-casted JSON result values;
20+
i.e. the conversion of `SELECT` query results returns a `list` of mappings with values of type `sparqlx.types.SPARQLResultBindingValue` (a union type `rdflib.URIRef | rdflib.BNode | sparqlx.types.LiteralToPython`).
21+
22+
23+
An important divergence from the SPARQL 1.2 Query Results JSON Format lies in how `sparqlx` handles `UNDEF` SPARQL bindings in `SELECT` result conversions.
24+
While `UNDEF` SPARQL bindings are actually *dropped entirely* for the respective result row in the standard Query Results JSON, `sparqlx` inspects the projection and guarantees stable result shapes by assigning `None` for `UNDEF` bindings.
25+
26+
Consider the following `VALUES` example:
27+
28+
```sparql
29+
select ?x
30+
where {
31+
values ?x {1 undef}
32+
}
33+
```
34+
35+
The raw JSON response for this query will be:
36+
37+
```json
38+
{
39+
"head": {
40+
"vars": [
41+
"x"
42+
]
43+
},
44+
"results": {
45+
"bindings": [
46+
{
47+
"x": {
48+
"datatype": "http://www.w3.org/2001/XMLSchema#integer",
49+
"type": "literal",
50+
"value": "1"
51+
}
52+
},
53+
{}
54+
]
55+
}
56+
}
57+
```
58+
59+
Note that the second binding map is empty.
60+
61+
62+
The same query with `SPARQLWrapper.query` and `convert=True` produces the following result of type `sparqlx.types.SPARQLResultBinding`:
63+
64+
```python
65+
[{'x': 1}, {'x': None}]
66+
```
67+
68+
This normalization of result shapes according to the query projection is convenient for SPARQL result processing e.g. with Pydantic models or the like.
69+
70+
71+
The explication of SPARQL `UNDEF` as `None`-bindings in `sparqlx` has subtle consequences that one should be aware of though.
72+
73+
| Query | `convert=False` | `convert=True` | Comment |
74+
|------------------------|----------------------------------------------------------------------------------|-----------------------|-------------------------------------------------------------------------|
75+
| `select ?dne where {}` | `{'head': {'vars': ['dne']}, 'results': {'bindings': [{}]}}` | `[{ 'dne': None }]` | `?dne` is in the projection and therefore present in the converted result. |
76+
| `select * where {}` | `{'head': {'vars': []}, 'results': {'bindings': [{}]}}` | `[{}]` | No variables in the projection, so no bindings appear in the con*
77+
78+
579

680
## `rdflib.Graph` Targets
781

0 commit comments

Comments
 (0)