2014-07-08 50 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' 

我的想法是,如果我尝试添加节点和他们已经在数据库中,他们不会被添加。

我已经做了一个尝试/除了创建/ add_labels行的AttributeError块,但是当我这样做时,我设法复制了已经在数据库中的所有东西,即使我显示了约束条件。 (?!?)(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)) 

此,没有这意味着节点满足约束条件仅应用于节点与标签ProgramSession任何标签首先创建节点。

一旦您调用newprogram.add_labels('Program')newsession.add_labels('Session') Neo4j尝试向节点添加标签并引发异常,因为无法满足约束断言。

Py2neo可能正在创建重复节点。虽然我确定如果你检查他们,你会发现一组节点有标签,另一组没有。

你可以使用py2neo来创建同时添加标签吗?

否则,你可以使用一个暗号查询

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

我忘了name:和{programname}之间的qs参数中的空格,这样就解决了。现在我只需要弄清楚如何接收CypherQuery结果! –

1

首先,堆栈跟踪建议一个应该在py2neo的最新版本中修正的错误(编写本文时为1.6.4)。有一个问题,错误详细信息丢失了预期的“异常”密钥,现在这个问题已经修复,因此升级应该会给你一个更好的错误信息。

但是,这只能解决错误报告错误。就约束问题本身而言,标签的节点创建和应用必须分两步执行是正确的。这是由于REST API中的限制,它不允许直接创建具有标签详细信息的节点。

py2neo的下一个版本将通过批处理在单个步骤中使这更容易/可能。但是现在,你可能想看一下Cypher的声明来执行这里其他答案中提到的创建和标签。

+1

感谢您的额外背景,Nigel!我会升级到最新版本。而且我从上面的答案中得到了所有符合Cypher查询的工作。 –