f-string: 不允许使用单个 '}' Python SPARQL 查询问题
f-string: single '}' is not allowed Python SPARQL Query problem
我在使用 python 代码格式化 SPARQL 查询时遇到问题。显示的错误是:
'SELECT Distinct ?article ?item ?itemLabel ?itemDescription (GROUP_CONCAT(DISTINCT(?entity_type); separator = ", ") AS ?entity_type_list) ?main_category ?wikipediaLabel (GROUP_CONCAT(DISTINCT(?altLabel); separator = ", ") AS ?altLabel_list) WHERE'
^
SyntaxError: f-string: single '}' is not allowed
我不知道我错过了什么,有人可以帮忙吗?
def search_wikidata_label(label,lang='ar'):
sparql_query = (
'SELECT Distinct ?article ?item ?itemLabel ?itemDescription (GROUP_CONCAT(DISTINCT(?entity_type); separator = ", ") AS ?entity_type_list) ?main_category ?wikipediaLabel (GROUP_CONCAT(DISTINCT(?altLabel); separator = ", ") AS ?altLabel_list) WHERE'
'{SERVICE wikibase:mwapi'
'{ bd:serviceParam wikibase:api "EntitySearch". bd:serviceParam wikibase:endpoint "www.wikidata.org".'
f'bd:serviceParam mwapi:search "{label}".'
f'bd:serviceParam mwapi:language "{lang}" .'
'?item wikibase:apiOutputItem mwapi:item .'
'?num wikibase:apiOrdinal true .}'
'?item wdt:P31 ?entity_type .'
'MINUS { ?item wdt:P31 wd:Q4167410}'
'OPTIONAL{ ?item wdt:P910 ?main_category}'
'OPTIONAL { ?item skos:altLabel ?altLabel .'
f'FILTER (lang(?altLabel) = "{lang}") }'
'OPTIONAL{ ?article schema:about ?item;schema:isPartOf <https://ar.wikipedia.org/>;schema:name ?wikipediaLabel}'
'OPTIONAL{ ?article schema:about ?item;schema:isPartOf <https://ar.wikipedia.org/>;schema:name ?wikipediaLabel}'
'SERVICE wikibase:label {'
f'bd:serviceParam wikibase:language "{lang}" .}'
'}'
'GROUP BY ?article ?item ?itemLabel ?itemDescription ?main_category ?wikipediaLabel'
)
#to query another endpoint, change the URL for the service and the query
sparql_service_url = "https://query.wikidata.org/sparql"
result_table = query_wikidata(sparql_query, sparql_service_url)
return result_table
如果你想要转义花括号,你需要将它们加倍:
>>> lang = "lang"
>>> f'FILTER (lang(?altLabel) = "{lang}") }}'
'FILTER (lang(?altLabel) = "lang") }'
>>> f'FILTER (lang(?altLabel) = "{lang}") }'
File "<stdin>", line 1
SyntaxError: f-string: single '}' is not allowed
检查:How can I print literal curly-brace characters in a string and also use .format on it?
因为 SPARQL 在其语法中使用 { 和 },并且因为您只替换了很少的值,所以我会避免使用 f 字符串并使用模板字符串,因为它使用 $ 来引入变量。更多信息请参阅 https://docs.python.org/3/library/string.html?highlight=string#template-strings。
如果您真的想坚持使用 f 字符串,那么在您希望结果中的文字 { 或 } 为 {{ 或 }} 的地方加倍 - 但这很漂亮太可怕了,特别是如果你想更新查询。使用模板字符串,您无需以任何方式修改查询,只需将 $ 变量引用放入其中即可。
此外,我发现将模板变量设为大写可以更容易地在模板中找到它们,例如(我还整理了您的 SPARQL 布局):
import string
sparql_query = '''
SELECT Distinct
?article
?item
?itemLabel
?itemDescription
(GROUP_CONCAT(DISTINCT(?entity_type); separator = ", ") AS ?entity_type_list)
?main_category
?wikipediaLabel
(GROUP_CONCAT(DISTINCT(?altLabel); separator = ", ") AS ?altLabel_list)
WHERE {
SERVICE wikibase:mwapi
{
bd:serviceParam wikibase:api "EntitySearch". bd:serviceParam wikibase:endpoint "www.wikidata.org" .
bd:serviceParam mwapi:search "$LABEL" .
bd:serviceParam mwapi:language "$LANG" .
?item wikibase:apiOutputItem mwapi:item .
?num wikibase:apiOrdinal true .
}
?item wdt:P31 ?entity_type .
MINUS { ?item wdt:P31 wd:Q4167410}
OPTIONAL {
?item wdt:P910 ?main_category
}
OPTIONAL {
?item skos:altLabel ?altLabel .
f'FILTER (lang(?altLabel) = "$LANG")
}
OPTIONAL {
?article schema:about ?item;schema:isPartOf <https://ar.wikipedia.org/>;schema:name ?wikipediaLabel
}
OPTIONAL {
?article schema:about ?item;schema:isPartOf <https://ar.wikipedia.org/>;schema:name ?wikipediaLabel
}
SERVICE wikibase:label {
bd:serviceParam wikibase:language "$LANG" .
}
}
GROUP BY ?article ?item ?itemLabel ?itemDescription ?main_category ?wikipediaLabel
'''
result = string.Template(sparql_query).substitute( LANG="ENGLISH", LABEL="MYLABEL" )
print( result )
结果:
SELECT Distinct
?article
?item
?itemLabel
?itemDescription
(GROUP_CONCAT(DISTINCT(?entity_type); separator = ", ") AS ?entity_type_list)
?main_category
?wikipediaLabel
(GROUP_CONCAT(DISTINCT(?altLabel); separator = ", ") AS ?altLabel_list)
WHERE {
SERVICE wikibase:mwapi
{
bd:serviceParam wikibase:api "EntitySearch". bd:serviceParam wikibase:endpoint "www.wikidata.org" .
bd:serviceParam mwapi:search "MYLABEL" .
bd:serviceParam mwapi:language "ENGLISH" .
?item wikibase:apiOutputItem mwapi:item .
?num wikibase:apiOrdinal true .
}
?item wdt:P31 ?entity_type .
MINUS { ?item wdt:P31 wd:Q4167410}
OPTIONAL {
?item wdt:P910 ?main_category
}
OPTIONAL {
?item skos:altLabel ?altLabel .
f'FILTER (lang(?altLabel) = "ENGLISH")
}
OPTIONAL {
?article schema:about ?item;schema:isPartOf <https://ar.wikipedia.org/>;schema:name ?wikipediaLabel
}
OPTIONAL {
?article schema:about ?item;schema:isPartOf <https://ar.wikipedia.org/>;schema:name ?wikipediaLabel
}
SERVICE wikibase:label {
bd:serviceParam wikibase:language "ENGLISH" .
}
}
GROUP BY ?article ?item ?itemLabel ?itemDescription ?main_category ?wikipediaLabel
我在使用 python 代码格式化 SPARQL 查询时遇到问题。显示的错误是:
'SELECT Distinct ?article ?item ?itemLabel ?itemDescription (GROUP_CONCAT(DISTINCT(?entity_type); separator = ", ") AS ?entity_type_list) ?main_category ?wikipediaLabel (GROUP_CONCAT(DISTINCT(?altLabel); separator = ", ") AS ?altLabel_list) WHERE'
^
SyntaxError: f-string: single '}' is not allowed
我不知道我错过了什么,有人可以帮忙吗?
def search_wikidata_label(label,lang='ar'):
sparql_query = (
'SELECT Distinct ?article ?item ?itemLabel ?itemDescription (GROUP_CONCAT(DISTINCT(?entity_type); separator = ", ") AS ?entity_type_list) ?main_category ?wikipediaLabel (GROUP_CONCAT(DISTINCT(?altLabel); separator = ", ") AS ?altLabel_list) WHERE'
'{SERVICE wikibase:mwapi'
'{ bd:serviceParam wikibase:api "EntitySearch". bd:serviceParam wikibase:endpoint "www.wikidata.org".'
f'bd:serviceParam mwapi:search "{label}".'
f'bd:serviceParam mwapi:language "{lang}" .'
'?item wikibase:apiOutputItem mwapi:item .'
'?num wikibase:apiOrdinal true .}'
'?item wdt:P31 ?entity_type .'
'MINUS { ?item wdt:P31 wd:Q4167410}'
'OPTIONAL{ ?item wdt:P910 ?main_category}'
'OPTIONAL { ?item skos:altLabel ?altLabel .'
f'FILTER (lang(?altLabel) = "{lang}") }'
'OPTIONAL{ ?article schema:about ?item;schema:isPartOf <https://ar.wikipedia.org/>;schema:name ?wikipediaLabel}'
'OPTIONAL{ ?article schema:about ?item;schema:isPartOf <https://ar.wikipedia.org/>;schema:name ?wikipediaLabel}'
'SERVICE wikibase:label {'
f'bd:serviceParam wikibase:language "{lang}" .}'
'}'
'GROUP BY ?article ?item ?itemLabel ?itemDescription ?main_category ?wikipediaLabel'
)
#to query another endpoint, change the URL for the service and the query
sparql_service_url = "https://query.wikidata.org/sparql"
result_table = query_wikidata(sparql_query, sparql_service_url)
return result_table
如果你想要转义花括号,你需要将它们加倍:
>>> lang = "lang"
>>> f'FILTER (lang(?altLabel) = "{lang}") }}'
'FILTER (lang(?altLabel) = "lang") }'
>>> f'FILTER (lang(?altLabel) = "{lang}") }'
File "<stdin>", line 1
SyntaxError: f-string: single '}' is not allowed
检查:How can I print literal curly-brace characters in a string and also use .format on it?
因为 SPARQL 在其语法中使用 { 和 },并且因为您只替换了很少的值,所以我会避免使用 f 字符串并使用模板字符串,因为它使用 $ 来引入变量。更多信息请参阅 https://docs.python.org/3/library/string.html?highlight=string#template-strings。
如果您真的想坚持使用 f 字符串,那么在您希望结果中的文字 { 或 } 为 {{ 或 }} 的地方加倍 - 但这很漂亮太可怕了,特别是如果你想更新查询。使用模板字符串,您无需以任何方式修改查询,只需将 $ 变量引用放入其中即可。
此外,我发现将模板变量设为大写可以更容易地在模板中找到它们,例如(我还整理了您的 SPARQL 布局):
import string
sparql_query = '''
SELECT Distinct
?article
?item
?itemLabel
?itemDescription
(GROUP_CONCAT(DISTINCT(?entity_type); separator = ", ") AS ?entity_type_list)
?main_category
?wikipediaLabel
(GROUP_CONCAT(DISTINCT(?altLabel); separator = ", ") AS ?altLabel_list)
WHERE {
SERVICE wikibase:mwapi
{
bd:serviceParam wikibase:api "EntitySearch". bd:serviceParam wikibase:endpoint "www.wikidata.org" .
bd:serviceParam mwapi:search "$LABEL" .
bd:serviceParam mwapi:language "$LANG" .
?item wikibase:apiOutputItem mwapi:item .
?num wikibase:apiOrdinal true .
}
?item wdt:P31 ?entity_type .
MINUS { ?item wdt:P31 wd:Q4167410}
OPTIONAL {
?item wdt:P910 ?main_category
}
OPTIONAL {
?item skos:altLabel ?altLabel .
f'FILTER (lang(?altLabel) = "$LANG")
}
OPTIONAL {
?article schema:about ?item;schema:isPartOf <https://ar.wikipedia.org/>;schema:name ?wikipediaLabel
}
OPTIONAL {
?article schema:about ?item;schema:isPartOf <https://ar.wikipedia.org/>;schema:name ?wikipediaLabel
}
SERVICE wikibase:label {
bd:serviceParam wikibase:language "$LANG" .
}
}
GROUP BY ?article ?item ?itemLabel ?itemDescription ?main_category ?wikipediaLabel
'''
result = string.Template(sparql_query).substitute( LANG="ENGLISH", LABEL="MYLABEL" )
print( result )
结果:
SELECT Distinct
?article
?item
?itemLabel
?itemDescription
(GROUP_CONCAT(DISTINCT(?entity_type); separator = ", ") AS ?entity_type_list)
?main_category
?wikipediaLabel
(GROUP_CONCAT(DISTINCT(?altLabel); separator = ", ") AS ?altLabel_list)
WHERE {
SERVICE wikibase:mwapi
{
bd:serviceParam wikibase:api "EntitySearch". bd:serviceParam wikibase:endpoint "www.wikidata.org" .
bd:serviceParam mwapi:search "MYLABEL" .
bd:serviceParam mwapi:language "ENGLISH" .
?item wikibase:apiOutputItem mwapi:item .
?num wikibase:apiOrdinal true .
}
?item wdt:P31 ?entity_type .
MINUS { ?item wdt:P31 wd:Q4167410}
OPTIONAL {
?item wdt:P910 ?main_category
}
OPTIONAL {
?item skos:altLabel ?altLabel .
f'FILTER (lang(?altLabel) = "ENGLISH")
}
OPTIONAL {
?article schema:about ?item;schema:isPartOf <https://ar.wikipedia.org/>;schema:name ?wikipediaLabel
}
OPTIONAL {
?article schema:about ?item;schema:isPartOf <https://ar.wikipedia.org/>;schema:name ?wikipediaLabel
}
SERVICE wikibase:label {
bd:serviceParam wikibase:language "ENGLISH" .
}
}
GROUP BY ?article ?item ?itemLabel ?itemDescription ?main_category ?wikipediaLabel