Как сделать пакетную вставку данных в GraphDB в транзакции - PullRequest
0 голосов
/ 11 октября 2019

Я пытаюсь вставить данные в GraphDB, поэтому запрос на обновление SPARQL состоит из операторов общего размера ~ 1M с некоторыми операторами DELETE и WHERE. Я не смог сделать это с помощью GraphDB REST API:

1) успешно запустил tansaction POST / repositories / {repositoryID} / Transactions 2) отправив запрос на обновление (фрагмент кода в python)

requests.put(
    url='/repositories/{repositoryID}/transactions/{transactionID}'
    params={'update': sparql, 'action': 'ADD'}
) 

получениеошибка

<!doctype html><html lang="en"><head><title>HTTP Status 400 – Bad Request</title><style type="text/css">h1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} h2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} h3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} b {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} p {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;} a {color:black;} a.name {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 400 – Bad Request</h1><hr class="line" /><p><b>Type</b> Exception Report</p><p><b>Message</b> Request header is too large</p><p><b>Description</b> The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).</p><p><b>Exception</b></p><pre>java.lang.IllegalArgumentException: Request header is too large

Эти операторы sparql успешно выполнялись в консоли Workbench SPARQL. Но если я увеличу количество данных, я получу

java.lang.StackOverflowError

в интерфейсе Workbench.

sparql, который я хочу выполнить, имеет следующий вид:

PREFIX time: <http://www.w3.org/2006/time#> 
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> 
PREFIX tr: <http://www.semanticweb.org/tr#> 
PREFIX owl: <http://www.w3.org/2002/07/owl#>  
PREFIX geosparql: <http://www.opengis.net/ont/geosparql#>

DELETE { tr:ontologyVersion tr:hasTimestamp ?o . }
INSERT {
    trip:ontologyVersion a time:Instant, owl:NamedIndividual ; 
                     trip:hasTimestamp "2019-10-11 14:56:06.750130+00:00"^^xsd:dateTime . 

    <a lot of new triples>
} 
WHERE { 
    OPTIONAL { tr:ontologyVersion tr:hasTimestamp ?o . } 
} 

Так каквставить данные в GraphDB, как правильно это сделать?

ОБНОВЛЕНИЕ 1

Я переписал код для использования

requests.put(url=url, data={'update': sparql}, params={'action': 'COMMIT'}) 

Ииспользуйте sparql = "УДАЛИТЬ ДАННЫЕ {}; ВСТАВИТЬ ДАННЫЕ {}". Запрос выполнен с кодом ответа 200, но по некоторым причинам данные отсутствуют в GraphDB.

ОБНОВЛЕНИЕ 2

Согласно REST4j REST API сервера REST Я изменил запросы на

requests.put(url=transaction_url, data={'update': sparql}, params={'action': 'UPDATE'}) 
requests.put(url=transaction_url, params={'action': 'COMMIT'}) 

И все еще использую sparql = "УДАЛИТЬ ДАННЫЕ {}; ВСТАВИТЬ ДАННЫЕ {}". Запрос с типом контента 'application / x-www-form-urlencoded' и кодировкой url sparql string.

В этом случае я получаю 406 ошибку

org.eclipse.rdf4j.http.server.ClientHTTPException: Could not read SPARQL update string from body.

Ответы [ 2 ]

2 голосов
/ 12 октября 2019

Здесь происходит две отдельные проблемы.

Первая проблема - когда вы пытаетесь выполнить обновление sparql как часть транзакции. Сообщение об ошибке «Заголовок запроса слишком велик». Для меня это звучит так, будто ваш запрос пытается отправить полезную нагрузку как поле заголовка, а не как полезную нагрузку данных. Я думаю, что вы можете немного изменить свой код Python, например:

requests.put(
    url='/repositories/{repositoryID}/transactions/{transactionID}'
    data={'update': sparql, 'action': 'ADD'}
) 

(поэтому data вместо params)

Вторая проблема звучит как ограничениепользовательский интерфейс Workbench (при условии, что именно это вызывает StackOverflowError), но кроме этого, способ вставки новых данных очень неэффективен: вы делаете необязательный запрос как часть массовой загрузки данных и используете INSERT. .. ГДЕ также.

Я бы предложил вместо этого использовать команду INSERT DATA для массовой загрузки:

INSERT DATA {
  // ... large amount of triples
}

Если эта вещь, которую вы делаете с отметкой времени, должна быть частьюДля достижения того, чего вы пытаетесь достичь, я предлагаю вам выполнить запрос и обновить эту временную метку как отдельные операции до или после массовой загрузки - если вы сделаете это для одной и той же транзакции, конечный результат будет таким же.

Да, и, конечно, как только вы закончите, вам нужно совершить транзакцию .

1 голос
/ 13 октября 2019

Наконец-то я придумал решение.

requests.put(url=transaction_url, data=sparql, params={'action': 'UPDATE'}, headers={'Conteny-Type': 'application/sparql-update'}) 
requests.put(url=transaction_url, params={'action': 'COMMIT'}) 

Как выяснилось, API транзакций RDF4J ожидает, что запрос будет в теле в том виде, в каком он есть, без какого-либо urlencoding и имени параметра update =. Нашел здесь java / org / eclipse / rdf4j / http / server / repository / транзакция / TransactionController.java

...