2016-07-12 3 views
3

Я пытался выяснить способ адаптации функциональности merge_one от py2neo v2 до v3. Я прочитал в Google group, что «Метод merge_one больше не существует в v3, так как вместо этого вы должны использовать слияние во всех случаях». но я не могу понять, как легко использовать регулярное слияние в v3.py2neo - обновление существующего узла с новыми свойствами с ограничением уникальности (merge_one)

Я пытаюсь воссоздать проект Nicole White's neo4j twitter example с небольшой модификацией. Она использовала merge_one. Существуют ограничения уникальности (u: User) - u.username и (t: Tweet) - t.id. Ее сценарий всегда имеет те же свойства для узлов Twitter и User, но я делаю случай, когда иногда я хочу вернуться и добавить дополнительные свойства к существующему узлу слиянием. Однако я получаю ошибку

py2neo.database.status.ConstraintError: Node 178 already exists with label Tweet and property "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) 

слияние не находит тот же твит со всеми этими свойствами и когда он пытается создать один, работает с ограничением уникальности идентификатора Tweet. Похоже, что функция 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 я бы сделал слияние только с идентификатором, а затем установил совпадение или установил на создание, но я не вижу, как это сделать с py2neo. Я также попытался найти в документации что-то, что позволит обновлять свойства из словаря с существующим узлом, но не может.

ответ

6

py2neo v3 теперь имеет graph.merge(), который вы можете использовать для того же эффекта.

Сначала найти или создать узел с graph.merge(), соответствие только на его уникальное свойство, а затем обновить свои другие не уникальные свойства с node.push(). Вам пришлось бы сделать то же самое с 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

Спасибо, я не понимал, что вы можете изменить свойства узла после слияния с таким нажатием. Ваш пример действительно полезен для обучения использованию neo4j и python с помощью Twitter! –

+0

Спасибо! Кроме того, я обновил сценарий, связанный с вашим вопросом, для использования py2neo v3. –

4

Две вещи;

1.) tweet.push() был устаревшим. Документы предлагают использовать graph.push (твит).

2.) У меня возникают проблемы, чтобы получить эту работу с транзакцией, такие как:

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

Любое предложение о разнице между использованием graph.merge и transaction.merge?

+0

На самом деле это не ответ, но мне удалось только заставить его работать, вызывая вызов метода push из транзакции ... –

Смежные вопросы