我有一个neo4j数据库,其节点有“Program”和“Session”标签。在Neo4j数据库中,我对属性强制执行唯一性约束:“name”和“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'
我的想法是,如果我尝试添加节点并且它们已经在数据库中,那么它们就不会被添加。
我在创建/ add_labels行周围尝试了/除了AttributeError块,但是当我这样做时,我设法复制了数据库中已有的所有内容,即使我已经显示了约束。 (?!?)(py2neo如何设法违反这些约束?)
我真的很困惑,并且非常感谢任何有关如何在节点尚不存在时添加节点的帮助。
答案 0 :(得分: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)
答案 1 :(得分:1)
首先,您已经显示的堆栈跟踪突出显示了一个错误,该错误应该在最新版本的py2neo中修复(在编写本文时为1.6.4)。有一个问题,错误细节丢失了预期的"异常"密钥,现在已经修复,因此升级应该会给你一个更好的错误信息。
但是,这只能解决错误报告错误。就约束问题本身而言,标签的节点创建和应用必须分两步执行是正确的。这是由于REST API中的限制,不允许使用直接方法创建具有标签详细信息的节点。
py2neo的下一个版本将通过批处理在一个步骤中使这更容易/更容易。但就目前而言,您可能希望查看Cypher声明,以执行此处其他答案中提到的创建和标记。