Skip to content

Instantly share code, notes, and snippets.

@pchampin
Last active November 5, 2020 09:22
Show Gist options
  • Save pchampin/ab3d01d2c3c245042dc5 to your computer and use it in GitHub Desktop.
Save pchampin/ab3d01d2c3c245042dc5 to your computer and use it in GitHub Desktop.
A subclass of rdflib SPARQLUpdateStore with BNode support, for Virtuoso
from rdflib import BNode, URIRef
from rdflib.plugins.stores.sparqlstore import SPARQLUpdateStore, _node_to_sparql, _node_from_result, SPARQL_NS
from uuid import uuid4
def _virtuoso_compatible_generator():
return unicode(uuid4().int % 2**61)
# monkey patch BNode to make it virtuoso compatible
BNode.__new__.func_defaults = (None, _virtuoso_compatible_generator, 'b')
def _virtuoso_node_to_sparql(node):
if isinstance(node, BNode):
return '<nodeID://{}>'.format(node)
else:
return node.n3()
def _virtuoso_node_from_result(element):
if element.tag == '{%s}bnode' % SPARQL_NS:
return BNode(element.text[9:])
else:
return _node_from_result(element)
class VSPARQLStore(SPARQLUpdateStore):
def __init__(self, endpoint, username, password, **kwargs):
SPARQLUpdateStore.__init__(self, endpoint, endpoint,
node_to_sparql=_virtuoso_node_to_sparql,
node_from_result=_virtuoso_node_from_result,
**kwargs)
self.setHTTPAuth('digest')
self.setCredentials(username, password)
if __name__ == "__main__":
from rdflib import Namespace, Graph, Literal
from rdflib.collection import Collection
EX = Namespace('http://example.org/')
store = VSPARQLStore('http://localhost:8890/sparql-auth', 'dba', 'dba')
g = Graph(store, EX.g)
g.remove((None, None, None))
print(len(g))
bn = BNode()
g.add((EX.s, EX.pb, bn))
g.add((bn, EX.pb, Literal("foo")))
lh = BNode()
g.add((EX.s, EX.pl, lh))
lst = Collection(g, lh, map(Literal, [1,2,3]))
print(len(g))
print(g.serialize(format="turtle"))
g.remove((None, None, None))
@joernhees
Copy link

... you seem to like living in the danger zone 😄

Monkeypatching obviously isn't that optimal, but to be honest i currently don't see a better way to do this (so being able to also configure BNode creation from a SPARQLStore in a way that doesn't have the potential to break things outside of it) ...

so, suggestions welcome, but till then 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment