簡體   English   中英

py2neo沒有在Neo4j數據庫中強制執行唯一性約束

[英]py2neo not enforcing uniqueness constraints in Neo4j database

我有一個帶有標簽為“ Program”和“ Session”的節點的neo4j數據庫。 在Neo4j數據庫中,我對屬性“名稱”和“ href”施加了唯一性約束。 從:schema

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'

我的想法是,如果我嘗試添加節點並且它們已經在數據庫中,那么就不會添加它們。

我已經在creation / add_labels行周圍完成了一個try / except AttributeError塊,但是當我這樣做時,即使有顯示的約束,我也設法復制了數據庫中已經存在的所有內容。 (?!?)(py2neo如何克服這些約束?

我真的很困惑,希望能幫助您確定僅在節點不存在時如何添加節點。

問題似乎在於,您首先要創建不帶標簽的節點,然后在創建后添加標簽。

那是

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

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

首先,創建沒有標簽的節點,這意味着節點滿足僅適用於帶有標簽ProgramSession的節點的約束條件。

一旦調用newprogram.add_labels('Program')newsession.add_labels('Session') Neo4j newsession.add_labels('Session')嘗試將標簽添加到節點並引發異常,因為無法滿足約束聲明。

Py2neo可能正在創建重復節點。 盡管我確定是否檢查了它們,但是您會發現一組節點具有標簽,而另一組則沒有標簽。

可以使用py2neo來在創建時同時添加標簽的方式嗎?

否則,您可以使用Cypher查詢

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

使用Py2neo,您應該能夠按照文檔中的建議進行操作

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)

首先,您顯示的堆棧跟蹤突出顯示了一個錯誤,該錯誤應在最新版本的py2neo(撰寫本文時為1.6.4)中進行修復。 存在一個問題,錯誤詳細信息刪除了預期的“ exception”鍵,並且此問題已得到解決,因此升級應為您提供更好的錯誤消息。

但是,這僅解決了錯誤報告錯誤。 就約束問題本身而言,節點的創建和標簽的應用必須分兩步執行是正確的。 這是由於REST API中的限制所致,不允許使用直接方法來創建帶有標簽詳細信息的節點。

py2neo的下一個版本將通過批處理在一個步驟中使此操作更容易/可行。 但就目前而言,您可能想要查看Cypher語句來執行創建和標記,如此處其他答案所述。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM