先把包导了,把Log也打印出来:
from py2neo import Node, Relationship, Graph, NodeMatcher,Subgraph
import logging
logging.basicConfig(level=logging.DEBUG, format="%(message)s")
两个点,一条关系,一个subgraph
a=Node('test',name='a')
b=Node('test',name='b')
r=Relationship(a,'knows',b,since=1000)
sub=Subgraph(relationships=[r])
graph = Graph("bolt://localhost:11003", name="*****", password="******")
测试反复create node
先试试create:
反复执行下面的代码:
tx=graph.begin()
tx.create(a)
graph.commit(tx)
第一遍的log,从Log中可以看到执行成功,从neo4j中查询也是能查到一个node
Attempting to acquire read-write connection to 'neo4j'
Using connection pool <py2neo.client.ConnectionPool object at 0x0000026605283DF0>
Trying to acquire connection from pool <py2neo.client.ConnectionPool object at 0x0000026605283DF0>
Connection <py2neo.client.bolt.Bolt4x3 object at 0x0000026605283B80> acquired by thread <_MainThread(MainThread, started 10172)>
[#CDAE] C: BEGIN {'db': 'neo4j'}
[#CDAE] C: (Sent 16 bytes)
[#CDAE] S: SUCCESS {}
**[#CDAE] C: RUN 'UNWIND $data AS r\nCREATE (_:test)\nSET _ += r\nRETURN id(_)' {'data': [{'name': 'a'}]} {}**
[#CDAE] C: PULL {'n': -1, 'qid': -1}
[#CDAE] C: (Sent 96 bytes)
[#CDAE] S: SUCCESS {'t_first': 1, 'fields': ['id(_)'], 'qid': 0}
[#CDAE] S: RECORD * 1
[#CDAE] S: SUCCESS {'stats': {'labels-added': 1, 'nodes-created': 1, 'properties-set': 1}, 'type': 'rw', 't_last': 0, 'db': 'neo4j'}
[#CDAE] C: COMMIT
[#CDAE] C: (Sent 6 bytes)
[#CDAE] S: SUCCESS {'bookmark': 'FB:kcwQo7NK3Nv+SpKE636V8mZyF8oAARe2kA=='}
Releasing connection <py2neo.client.bolt.Bolt4x3 object at 0x0000026605283B80> from thread <_MainThread(MainThread, started 10172)>
执行第2,3,4,5…遍:
发现python并没有向neo4j发送什么东西,自然就不会再创建node了。也就是说,反复执行并不会重复创建node,执行merge也有类似的情况。
Attempting to acquire read-write connection to 'neo4j'
Using connection pool <py2neo.client.ConnectionPool object at 0x0000026605283DF0>
Trying to acquire connection from pool <py2neo.client.ConnectionPool object at 0x0000026605283DF0>
Connection <py2neo.client.bolt.Bolt4x3 object at 0x0000026605283B80> acquired by thread <_MainThread(MainThread, started 10172)>
[#CDAE] C: BEGIN {'db': 'neo4j'}
[#CDAE] C: (Sent 16 bytes)
[#CDAE] S: SUCCESS {}
[#CDAE] C: COMMIT
[#CDAE] C: (Sent 6 bytes)
[#CDAE] S: SUCCESS {'bookmark': 'FB:kJA='}
Releasing connection <py2neo.client.bolt.Bolt4x3 object at 0x0000026605283B80> from thread <_MainThread(MainThread, started 10172)>
可以看到,neo4j中只有这一个点:
如果在neo4j里如果我们把点和关系全部清空,再在python执行create时,也不会重新创建点和关系。而当有这种需要反复删除和创建的场景却无法创建点和关系时,问题就变的很可恶了!!
问题分析然而这是为什么呢?需要我们对源码进行分析。通过pycharm跟踪发现,在create的过程中,会把subgraph中的nodes和relationships进行is_bound的判断,也就是判断是否已绑定过这一entity,当nodes或relationship的graph为空时,即没有graph与entity绑定,则会创建这个entity,如果不为空,则认为entity已经和graph绑定了,也就是创建过了,所以也就不会重复创建了。
但是这个设计会带来被删除的实体无法重复创建的问题。
node_dict = {}
for node in self.nodes:
if not self.**_is_bound**(node, tx.graph):
key = frozenset(node.labels)
node_dict.setdefault(key, []).append(node)
# Convert relationships into a dictionary of
# {rel_type: [Rel, Rel, ...]}
rel_dict = {}
for relationship in self.relationships:
if not self.**_is_bound**(relationship, tx.graph):
key = type(relationship).__name__
rel_dict.setdefault(key, []).append(relationship)
def _is_bound(cls, entity, graph):
if entity.graph is None:
return False
elif entity.graph == graph:
return True
else:
raise ValueError("Entity %r is already bound to graph %r" % (entity, graph))
解决思路
如果在neo4j中已经删除node或relationship,但想利用py2neo重复创建点,可以把这个entity的graph赋值为None,就可以再次创建了。
a.graph=None
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)