2014-07-08 4 views
1

У меня есть база данных neo4j с узлами, которые имеют метки «Программа» и «Сессия». В базе данных Neo4j я применял ограничение уникальности свойств: «name» и «href». От: схемаpy2neo не применяет ограничения уникальности в базе данных Neo4j

Constraints 
ON (program:Program) ASSERT program.href IS UNIQUE 
ON (program:Program) ASSERT program.name IS UNIQUE 
ON (session:Session) ASSERT session.name IS UNIQUE 
ON (session:Session) ASSERT session.href IS UNIQUE 

Я хочу периодически запрашивать другой API (таким образом, хранящее имя и API конечного HREF как свойства), и только добавлять новые узлы, когда они уже не в базе данных.

Это, как я создаю узлы:

newprogram, = graph_db.create(node(name = programname, href = programhref)) 
newprogram.add_labels('Program') 

newsession, = graph_db.create(node(name = sessionname, href = sessionhref)) 
newsession.add_labels('Session') 

Я бегу в следующее сообщение об ошибке:

Traceback (most recent call last): 
    File "/Users/jedc/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1535, in __call__ 
    rv = self.handle_exception(request, response, e) 
    File "/Users/jedc/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1529, in __call__ 
    rv = self.router.dispatch(request, response) 
    File "/Users/jedc/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher 
    return route.handler_adapter(request, response) 
    File "/Users/jedc/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1102, in __call__ 
    return handler.dispatch() 
    File "/Users/jedc/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 572, in dispatch 
    return self.handle_exception(e, self.app.debug) 
    File "/Users/jedc/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 570, in dispatch 
    return method(*args, **kwargs) 
    File "/Users/jedc/appfolder/applicationapis.py", line 42, in post 
    newprogram.add_labels('Program') 
    File "/Users/jedc/appfolder/py2neo/util.py", line 99, in f_ 
    return f(*args, **kwargs) 
    File "/Users/jedc/appfolder/py2neo/core.py", line 1638, in add_labels 
    if err.response.status_code == BAD_REQUEST and err.cause.exception == 'ConstraintViolationException': 
AttributeError: 'ConstraintViolationException' object has no attribute 'exception' 

Моя мысль в том, что если я пытаюсь добавить узлы и они 're уже в базе данных они просто не будут добавлены.

Я сделал блок try/except AttributeError вокруг строк creation/add_labels, но когда я это сделал, мне удалось дублировать все, что было уже в базе данных, хотя у меня были указанные ограничения. (?!?) (Как может py2neo нарушить эти ограничения?)

Я действительно смущен и буду признателен за любую помощь в определении того, как добавлять узлы только тогда, когда они еще не существуют.

+0

Ограничение не будет нарушено, пока вы не добавите метку, которую вы делаете после создания узла. Таким образом, узел создается, но add_label должен завершиться неудачей. –

+0

Я думаю, что другой вопрос: могу ли я добавить ограничения, не привязанные к ярлыкам? (Я предполагаю, что не могу.) –

+0

Можете ли вы сделать это в одном заявлении? graph.create (узел) .add_label()? –

ответ

3

Проблема заключается в том, что вы сначала создаете узлы без метки, а затем добавляете ярлык после создания.

Это

graph_db.create(node(name = programname, href = programhref)) 

и

graph_db.create(node(name = sessionname, href = sessionhref)) 

Это, во-первых, создает узлы без каких-либо меток, что означает, что узлы удовлетворяют условиям ограничений, которые применяются только к узлам с метками Program и Session.

Как только вы вызываете newprogram.add_labels('Program') и newsession.add_labels('Session') Neo4j пытается добавить метки к узлу и вызывает исключение, поскольку утверждения ограничения не могут быть выполнены.

Py2neo может создавать дублирующие узлы. Хотя я уверен, что если вы их осмотрите, вы обнаружите, что один набор узлов имеет метки, а другой набор - нет.

Можете ли вы использовать py2neo таким образом, чтобы он добавлял метку одновременно с созданием?

В противном случае вы можете использовать Cypher запрос

CREATE (program:Program{name: {programname}, href: {programhref}}) 
CREATE (session:Session{name: {sessionname}, href: {sessionhref}}) 

Использование Py2neo вы должны быть в состоянии сделать это, как предложено в docs

graph_db = neo4j.GraphDatabaseService() 
qs = '''CREATE (program:Program{name: {programname}, href: {programhref}}) 
     CREATE (session:Session{name: {sessionname}, href: {sessionhref}})''' 
query = neo4j.CypherQuery(graph_db, qs) 
query.execute(programname=programname, programhref=programhref, 
       sessionname=sessionname, sessionhref=sessionhref) 
+0

Ах, конечно. Я пробовал несколько разных подходов и просто обернулся вокруг оси. Я реализовал это, и теперь я получаю сообщение об ошибке в строке query.execute с параметром ParameterNotFoundException: ожидается параметр с именем programname. Я неправильно понимаю синтаксис? –

+0

Я забыл пробел в аргументе qs между именем: и {programname}, так что это решило. Теперь мне просто нужно выяснить, как получить результаты CypherQuery! –

1

Во-первых, трассировки стека, что вы показали основные моменты aa, который должен быть исправлен в последней версии py2neo (1.6.4 на момент написания). Возникла проблема, при которой информация об ошибке выпадала из ожидаемого «исключения», и теперь это исправлено, поэтому обновление должно дать вам лучшее сообщение об ошибке.

Однако это касается только ошибки сообщения об ошибках. В терминах самого вопроса ограничения корректно, что создание узлов и применение меток обязательно выполняются в два этапа. Это связано с ограничением в REST API, который не позволяет прямому методу создания узла с меткой.

Следующая версия py2neo сделает это проще/возможно за один шаг путем пакетной обработки. Но пока вы, вероятно, захотите посмотреть на заявление Cypher, чтобы выполнить создание и маркировку, как указано в другом ответе здесь.

+1

Спасибо за дополнительный контекст, Найджел! Я перейду к новой версии. И с тех пор я получил все, чтобы работать с запросами Cypher за ответ выше. –

Смежные вопросы