2015-12-22 9 views
0

Я пытаюсь загрузить некоторые данные в Dydra из трипстора Сезам, который у меня есть на моем компьютере. В то время как загрузка с Сезам работает нормально, тройки смешиваются (отношения s-p-o изменяются, поскольку объект одного становится объектом другого). Может кто-нибудь объяснить, почему это происходит и как это можно решить? Код ниже:Как предотвратить перемещение троек при загрузке в Dydra программно?

#Querying the triplestore to retrieve all results 
sesameSparqlEndpoint = 'http://my.ip.ad.here:8080/openrdf-sesame/repositories/rep_name' 
sparql = SPARQLWrapper(sesameSparqlEndpoint) 
queryStringDownload = 'SELECT * WHERE {?s ?p ?o}' 
dataGraph = Graph() 

sparql.setQuery(queryStringDownload) 
sparql.method = 'GET' 
sparql.setReturnFormat(JSON) 
output = sparql.query().convert() 
print output 

for i in range(len(output['results']['bindings'])): 
    #The encoding is necessary to parse non-English characters 
    output['results']['bindings'][i]['s']['value'].encode('utf-8') 
    try: 
     subject_extract = output['results']['bindings'][i]['s']['value'] 
     if 'http' in subject_extract: 
      subject = "<" + subject_extract + ">" 
      subject_url = URIRef(subject) 
      print subject_url 

     predicate_extract = output['results']['bindings'][i]['p']['value'] 
     if 'http' in predicate_extract: 
      predicate = "<" + predicate_extract + ">" 
      predicate_url = URIRef(predicate) 
      print predicate_url 

     objec_extract = output['results']['bindings'][i]['o']['value'] 
     if 'http' in objec_extract: 
      objec = "<" + objec_extract + ">" 
      objec_url = URIRef(objec) 
      print objec_url 
     else: 
      objec = objec_extract 
      objec_wip = '"' + objec + '"' 
      objec_url = URIRef(objec_wip) 

     # Loading the data on a graph  
     dataGraph.add((subject_url,predicate_url,objec_url)) 

    except UnicodeError as error: 
     print error 

#Print all statements in dataGraph  
for stmt in dataGraph: 
    pprint.pprint(stmt) 

# Upload to Dydra 
URL = 'http://dydra.com/login' 
key = 'my_key' 

with requests.Session() as s: 
    resp = s.get(URL) 
    soup = BeautifulSoup(resp.text,"html5lib") 
    csrfToken = soup.find('meta',{'name':'csrf-token'}).get('content') 
    # print csrf_token 
    payload = { 
    'account[login]':key, 
    'account[password]':'', 
    'csrfmiddlewaretoken':csrfToken, 
    'next':'/' 
    } 
    # print payload 

    p = s.post(URL,data=payload, headers=dict(Referer=URL)) 
    # print p.text 

    r = s.get('http://dydra.com/username/rep_name/sparql') 
    # print r.text 

    dydraSparqlEndpoint = 'http://dydra.com/username/rep_name/sparql' 
    for stmt in dataGraph: 
     queryStringUpload = 'INSERT DATA {%s %s %s}' % stmt 
     sparql = SPARQLWrapper(dydraSparqlEndpoint) 
     sparql.setCredentials(key,key) 
     sparql.setQuery(queryStringUpload) 
     sparql.method = 'POST' 
     sparql.query() 
+0

Ничего себе. Вы проделали долгий путь здесь. Почему вы используете SELECT-запрос для извлечения всех троек (и прыгаете через все виды обручей, чтобы восстановить фактические тройки RDF из результата запроса), вместо использования запроса CONSTRUCT (который дает вам результат, готовый как заявления RDF)? –

+1

Ну, это неловко; Я должен был подумать об этом. Просто делать это, кажется, сделать трюк: sesameSparqlEndpoint = 'http://my.ip.ad.here:8080/openrdf-sesame/repositories/rep_name' SPARQL = SPARQLWrapper (sesameSparqlEndpoint) queryStringDownload = «CONSTRUCT {? s? p? o} WHERE {? s? p? o} ' dataGraph = Graph() – kurious

+0

У меня возникают проблемы с итерацией по выходному запросу CONSTRUCT. Следующий вопрос: http://stackoverflow.com/questions/34425876/how-to-iterate-over-construct-output-from-rdflib. – kurious

ответ

1

Гораздо более простой способ для копирования данных через (кроме использования конструкта запроса вместо SELECT, как я уже говорил в комментарии) просто иметь Dydra сам непосредственно получить доступ к Сезаму конечной точки, например, посредством предложения SERVICE.

Выполните следующие действия на вашей базе данных Dydra, и (через некоторое время, в зависимости от того, насколько велика ваша база данных Сезам), все будет скопирован:

INSERT { ?s ?p ?o } 
    WHERE { 
     SERVICE <http://my.ip.ad.here:8080/openrdf-sesame/repositories/rep_name> 
     { ?s ?p ?o } 
    } 

Если выше не работает на Dydra , вы можете просто напрямую обращаться к операторам RDF из вашего магазина Sesame, используя URI http://my.ip.ad.here:8080/openrdf-sesame/repositories/rep_name/statements. Предполагая, что у Dydra есть функция загрузки, где вы можете указать URL-адрес документа RDF, вы можете просто предоставить ему вышеуказанный URI, и он должен иметь возможность загрузить его.

+0

Кажется, что требуется разрешение от Dydra для использования предложения SERVICE. В противном случае это, вероятно, самый безболезненный способ переноса данных. – kurious

0

Код выше может работать, если выполнены следующие изменения:

  1. Используйте CONSTRUCT запрос вместо SELECT. Подробности здесь ->How to iterate over CONSTRUCT output from rdflib?
  2. Используйте ключ в качестве входных данных как для учетной записи [логин] и счета [пароль]

Однако, это, вероятно, не самый эффективный способ. В первую очередь, делать отдельные ВСТАВКИ для каждой тройки - это не очень хороший способ. Dydra не записывает все заявления таким образом (у меня вставлено только около 30% троек). Напротив, использование метода http://my.ip.ad.here:8080/openrdf-sesame/repositories/rep_name/statements, предложенного Джином, позволяло мне успешно переносить все данные.