假设你有一个非常简单的图表。
In [5]: node = py2neo.Node('LABEL', key='value')
In [6]: node_two = py2neo.Node('LABEL', key='value2')
In [7]: graph.create(py2neo.Relationship(node, 'IS_RELATED_TO', node_two))
此时node
绑定。尽管在{v3}中似乎删除了node.bound
布尔值,但您可以通过检查其__remote__
属性来看到这一点。
In [8]: node.__remote__
Out[8]: <RemoteEntity graph=u'http://localhost:7474/db/data/' ref=u'node/53983'>
节点也类似于dict,因此可以使用双splat解包(**
)复制它们。但是,这不会复制__remote__
,而是new_node
未绑定。
In [9]: new_node = py2neo.Node(**node)
In [10]: new_node.__remote__ is None
Out[10]: True
这有一个令人遗憾的副作用,new_node
不能用作期望绑定节点的几种方法的目标,例如match_one
:
In [11]: graph.match_one(new_node, 'IS_RELATED_TO', node_two)
TypeError: Nodes for relationship match end points must be bound
用例:子类化。如果我继承py2neo.Node
,我必须从py2neo.Node
(由大多数py2neo
方法返回)转换为我的子类。但是,然后取消绑定节点,这使得它对其他py2neo
方法毫无用处,从而首先破坏了子类化的目的。
解决方法:如果我设置new_node.__remote__ = node.__remote__
,这似乎有效,根据定义绑定new_node
。但是,我对搞乱第三方双下划线属性有一种有趣的感觉。我不确定这是否得到支持,我很肯定它没有证件。它可能有我不知道的副作用。
According to the documentation on Node,这似乎是官方解决方案:
在初始状态下,节点未绑定。这意味着它仅存在于客户端上,并且不引用相应的服务器节点。在Neo4j数据库中,节点通常由creating 绑定。
这表明处理未绑定副本(new_node
)的正确方法是使用graph.create
。但是,这会向图表添加一个新的不需要的节点,没有标签和与node
相同的属性。我可以使用graph.merge
代替,以防止创建不需要的重复,但这会覆盖图中的属性,new_node
上的任何内容,我并不总是想要。
那你怎么把py2neo.Node
转换成任何其他类型(或复制它)而不完全破坏py2neo工作流程呢?
我已经打开了一个相关的issue on GitHub,如果他没有在这里发布,我会从维护者那里得到的任何信息都会更新这个问题。