2

I have the following codes:

name = [str(s) for s,  in graph.query('''
    SELECT ?lbl 
    WHERE {
        <http://www.wikidata.org/entity/Q59692464> <http://www.wikidata.org/prop/direct/P1657> ?obj .
        ?obj rdfs:label ?lbl .
    }
    ''')]

I want to pass the two values<http://www.wikidata.org/entity/Q59692464>and <http://www.wikidata.org/prop/direct/P1657> as variables ?mov and ?rel.

I tried to use %s but got an error:

name = [str(s) for s,  in graph.query('''
    SELECT ?lbl 
    WHERE {
        <'%s'> <http://www.wikidata.org/prop/direct/P1657> ?obj .
        ?obj rdfs:label ?lbl .
    }
    '''%mov)]
TypeError: unsupported operand type(s) for %: 'SPARQLResult' and 'str'

What I want is something like this:

name = [str(s) for s,  in graph.query('''
    SELECT ?lbl 
    WHERE {
        ?mov ?rel ?obj .
        ?obj rdfs:label ?lbl .
    }
    ''')]

Thanks a lot for your help!

Ohrwurm
  • 21
  • 2
  • 1.) your code looks more like rdflib and not sparqlwrapper, thus, if you didn't load anything from Wikidata into the `graph`, it will be empty for obvious reasons. So if you didn't load some Wikidata fragment into your rdflib graph, then you should follow the documentation of sparqlwrapper instead: https://sparqlwrapper.readthedocs.io/en/latest/main.html – UninformedUser Dec 09 '22 at 07:40
  • 2) why do you put `%s` in to single quotes? The whole multiline string IS already a string, inlining string variables just needs an `%s` – UninformedUser Dec 09 '22 at 07:40
  • 3) do you really want all the labels? If not, put a `FILTER` in your SPARQL query – UninformedUser Dec 09 '22 at 07:42
  • `from SPARQLWrapper import SPARQLWrapper, JSON mov = 'http://www.wikidata.org/entity/Q59692464' sparql = SPARQLWrapper("https://query.wikidata.org/sparql") sparql.setReturnFormat(JSON) sparql.setQuery(''' SELECT ?lbl WHERE { <%s> ?obj . ?obj rdfs:label ?lbl . FILTER(lang(?lbl) = "en") } ''' % mov) try: ret = sparql.queryAndConvert() for r in ret["results"]["bindings"]: print(r['lbl']['value']) except Exception as e: print(e)` – UninformedUser Dec 09 '22 at 07:44

2 Answers2

2

Assuming you use rdflib, you can do something like this:

mov = rdflib.URIRef("http://www.wikidata.org/entity/Q59692464")
rel = rdflib.URIRef("http://www.wikidata.org/prop/direct/P1657")

name = [str(s) for s, in graph.query('''
SELECT ?lbl 
WHERE {
  ?mov ?rel ?obj .
  ?obj rdfs:label ?lbl .
}
''', initBindings={'mov': mov, 'rel': rel})]
1

You can try using double curly braces and the .format method. See:

name = [str(s) for s in graph.query('''
    SELECT ?lbl 
    WHERE {{
        {} {} ?obj .
        ?obj rdfs:label ?lbl .
    }}
    '''.format("<http://www.wikidata.org/entity/Q59692464>", "<http://www.wikidata.org/prop/direct/P1657>"))]

I would probably break this up and format the query as a string, and then call graph.query():

skeleton_query = '''
    SELECT ?lbl 
    WHERE {{
        {} {} ?obj .
        ?obj rdfs:label ?lbl .
    }}
    '''

formatted_query = skeleton_query.format("<http://www.wikidata.org/entity/Q59692464>", "<http://www.wikidata.org/prop/direct/P1657>")

result = graph.query(formatted_query)

HES
  • 160
  • 7