py2neo - 使用新属性 w/uniqueness 约束更新现有节点 (merge_one)

py2neo - updating existing node with new properties w/uniqueness constraint (merge_one)

我一直在尝试找出一种方法来将 merge_one 功能从 py2neo v2 调整到 v3。我在 Google group 中读到 "The merge_one method no longer exists in v3 as you should be able to use merge in all cases instead." 但我不知道如何在 v3.

中轻松使用常规合并

我正在尝试通过小的修改重新创建 Nicole White's neo4j twitter example 项目。她用了merge_one。 (u:User) - u.username 和 (t:Tweet) - t.id 存在唯一性约束。她的脚本对于 Tweet 和 User 节点始终具有相同的属性,但我正在做一个案例,有时我想返回并通过合并向现有节点添加更多属性。但是我收到错误

py2neo.database.status.ConstraintError: Node 178 already exists with label Tweet and property "id"=[***]

我理解这是因为当我有一个推文时,例如已经存在的只有一个 id 然后我尝试做

        tw_dict = {'id'=t['id'], 'text':t['text'], 'created':t['created_at'],
               'rts':t['retweet_count'],
               'favs':t['favorite_count'], 'lang':t['lang']}
        tweet = Node("Tweet", **tw_dict)
        graph.create(tweet)

merge 没有找到具有所有这些属性的相同推文,当它尝试创建一个时 运行 进入推文 ID 的唯一性约束。看起来 merge_one 函数可以解决这个问题,但它在 v3 中不可用。因此,我实施了以下内容:

    exists = graph.find_one("Tweet", "id", t['id'])
    if exists:
        exists['text'] = t['text']
        exists['created'] = t['created_at']
        exists['rts'] = t['retweet_count']
        exists['favs'] = t['favorite_count']
        exists['lang'] = t['lang']
    else:
        tw_dict = {'text':t['text'], 'created':t['created_at'],
               'rts':t['retweet_count'],
               'favs':t['favorite_count'], 'lang':t['lang']}
        tweet = Node("Tweet", **tw_dict)
        graph.create(tweet)

但这对我来说似乎是重复的。在 py2neo 中没有更简单的方法来做一些事情,比如用新属性更新现有节点并仍然指定具有唯一约束(在本例中为 id)的 属性 吗?我想在 Cypher 中,我会只对 id 进行合并,然后在匹配时设置或在创建时设置,但我不知道如何使用 py2neo 来做到这一点。我还试图在文档中找到一些允许从具有现有节点的字典更新属性但不能的东西。

py2neo v3 现在有 graph.merge(),你可以使用它达到同样的效果。

首先找到或创建具有 graph.merge() 的节点,在其唯一 属性 上仅匹配 ,然后使用 [= 更新其其他非唯一属性13=]。您将不得不对 graph.merge_one() 做同样的事情,只是语法略有不同。

from py2neo import Graph, Node
graph = Graph()

tweet = Node('Tweet', id=123)
graph.merge(tweet)
tweet['text'] = 'Hello World'
tweet.push()

我应该更新 Twitter 脚本以使用 py2neo v3;谢谢提醒。

两件事;

1.) tweet.push() 已被弃用。文档建议使用 graph.push(tweet).

2.) 我在处理以下交易时遇到问题:

transaction = graph.begin()
transaction.merge(tweet)
transaction.graph.push(tweet)
transaction.commit()

关于使用 graph.mergetransaction.merge 之间的区别有什么建议吗?

要更新 py2neo v5 - 2020,您可以从字典中更新现有节点的多个属性。

from py2neo import NodeMatcher
tw_dict = {'text':t['text'], 
           'created':t['created_at'],
           'rts':t['retweet_count'],
           'favs':t['favorite_count'], 
           'lang':t['lang']}
tweet = matcher.match('Tweet', id=123).first()
if tweet:
    tweet.update(**properties)
    graph.push(tweet)