Node added to neo4j DB but prints out as "None" - python

I have the following code:
import py2neo
from py2neo import Graph, Node, Relationship
def createRelationshipWithProperties():
print("Start - Creating Relationships")
# Authenticate the user using py2neo.authentication
# Ensure that you change the password 'sumit' as per your database configuration.
py2neo.authenticate("localhost:7474", "neo4j", "")
# Connect to Graph and get the instance of Graph
graph = Graph("http://localhost:7474/db/data/")
# Create Node with Properties
amy = Node("FEMALE", name="Amy")
# Create one more Node with Properties
kristine = Node("FEMALE",name="Kristine")
# Create one more Node with Properties
sheryl = Node("FEMALE",name="Sheryl")
kristine_amy = Relationship(kristine,"FRIEND",amy,since=2005)
print (kristine_amy)
amy_sheryl = Relationship(sheryl,("FRIEND"),amy,since=2001)
#Finally use graph Object and Create Nodes and Relationship
#When we create Relationship between, then Nodes are also created.
resultNodes = graph.create(kristine_amy)
resultNodes1 = graph.create(amy_sheryl)
#Print the results (relationships)
print("Relationship Created - ",resultNodes)
print("Relationship Created - ",resultNodes1)
if __name__ == '__main__':
createRelationshipWithProperties()
The resultsNodes = graph.create line seems to commit the nodes and relationships to the server because I can see them when I match(n) Return n. However, when the code prints resultsNodes, I get None as if they don't exist. This is the output that I get:
Start - Creating Relationships
(kristine)-[:FRIEND {since:2005}]->(amy)
Relationship Created - None
Relationship Created - None

You're using the API incorrectly. The create method doesn't return nodes but instead updates the supplied argument. Therefore to get the relationship nodes, you need to interrogate the relationship object after performing the create.

Related

Assign user to tasks automatically (Viewflow, Django)

I'm using Viewflow/Django and trying to assign tasks created by dynamic nodes.
I'm using the same nodes.py in customnode.
However, I need to automatically assign each new task based on information in the MOCTask model (the assignee).
But tasks don't allow an Assign with anything other than a specific user object and I don't have access to the MOCTask objects (they are related by foreign key to MOC, which is related by foreign key to MOCProcess, the flow itself).
My code I was trying (flows.py):
...
split_on_task_assignment = (
DynamicSplit(lambda p: MOCTask.objects.filter(MOC=p.MOC).count())
.IfNone(this.end)
.Next(this.task_completion)
)
task_completion = (
flow.View(views.TaskCompletion)
.Permission('MOC.is_MOC_actor')
.Assign(this.assign_actors)
.Next(this.join_on_task_completion)
)
...
def assign_actors(self, activation):
task = MOCTask.objects.filter(MOC=activation.process.MOC, assigned=False).first()
task.assigned = True
task.save()
return User.objects.filter(email=task.assignee).first()
However, I can't put a this reference in the assign block, so I'm not sure how to proceed.
Any ideas?
Users can be assigned inside DynamicSplitActivation when subsequent tasks are created
def activate_next(self):
if self._split_count:
token_source = Token.split_token_source(
self.task.token, self.task.pk)
for _ in range(self._split_count):
activation = self.flow_task._next.activate(
prev_activation=self, token=next(token_source))
activation.activate(..a user..)

How do I import Python node dicts into neo4j?

I produce the following node and relationship data in a for loop about 1 million times. The idea is that investor nodes connect to company nodes by relationship edges:
investor = {'name': owner['name'],
'CIK': owner['CIK']}
relationship = {'isDirector': owner['isDirector'],
'isOfficer': owner['isOfficer'],
'isOther': owner['isOther'],
'isTenPercentOwner': owner['isTenPercentOwner'],
'title': owner['title']}
company = {'Name': json['issuerName'],
'SIC': json['issuerSIC'],
'Ticker Symbol': json['issuerTradingSymbol'],
'CIK': json['issuerCIK'],
'EIN': json['issuerEIN']}
How do I complete the following code to get the dicts above into neo4j community edition?
from py2neo import Graph, authenticate
authenticate("localhost:7474", "neo4j", "neo")
graph = Graph()
for json in long_list_of_dicts:
investor = {...}
company = {...}
relationship = {...}
# Code to import investor, company, relationship data into neo4j
In py2neo a Node is defined in following manner:
class Node(*labels, **properties)
Each node has a label and can have many properties. In this case, Investor node can de defined by setting the label investor and properties of the node to be name and CIK.
investor_node = Node('investor', name = owner['name'], CIK = owner['CIK'])
Similarly, company node would look like:
company_node = Node('company', name = json['issuerName'], SIC = json['issuerSIC'])
Relationship are defined in following manner :
class Relationship(start_node, type, end_node, **properties)
In this case Relationship can be defined using:
investor_company_relationship = Relationship(investor_node, "is_director", company_node)
You can find one sample implementation of neo4j graph here.
You could use UNWIND clause. Something like
WITH {json} AS document
UNWIND document AS company
MERGE (c:company {c_id:company.id})
SET c.sic=company.issuerSIC
If some of your json items is list again, you can use UNWIND as much as you like: UNWIND document.list_of_some_property

Creating a relationship between 2 newly created nodes

I need to create a relationship between two newly created nodes,but it's creating another two nodes without creating a relationship between them.
I need to know how to get data from py2neo cypher query
def enter_products():
if request.method == 'POST':
data = request.get_json(True)
params = {"data": {"name":data['name']}}
products=graph.cypher.execute(" create(a:Products {data}) RETURN (a)", params)
CR_brand= {"data": {"brand":data['brand']}}
brands=graph.cypher.execute("merge(b:Brand {brand:{data}.brand})
RETURN (b)",CR_brand)
relation_brand=graph.cypher.execute("create(a:name)-[c:product_of]->(b:brand)")
RETURN 'OK'
You either can do it all in one statement:
create(a:Products {data})
merge(b:Brand {brand:{data}.brand}
create(a)-[:product_of]->(b)
or you have to look up by their key-property.
create(a:Products {name:{data}.name})-[c:product_of]->(b:Brand {data}.brand)

py2neo (1.6) how to get an existing node by node property without CypherQuery

I'm using py2neo (version 1.6). I want to get an existing node by its property from the graph and then use it to create a relationship.
My solution:
graph = neo4j.GraphDatabaseService("http://...")
query = neo4j.CypherQuery(graph,"MATCH (n:NodeType) where n.property = 'property' return n")
r = query.execute()
if len(r.data)==0:
raise Exception("node does not exist")
node = r.data[0]['n']
newNode = batch.create(node(name="APropertyOfNewNode"))
batch.add_labels(newNode, "LableOfNewNode")
relation = rel(node, "relationshipName", newNode)
batch.create(relation)
batch.submit()
batch.clear()
Is there an high level way to get an existing node by its property without using CypherQuery and writing plain cypher?
You can use GraphDatabaseService.find:
from py2neo import neo4j
graph = neo4j.GraphDatabaseService('http://localhost:7474/db/data/')
movies = graph.find('Movie', 'title', 'The Matrix')
But graph.find returns a generator object.
movies
# <generator object find at 0x10b64acd0>
So you can only iterate through it once.
for movie in movies:
print type(movie)
print movie['tagline']
# <class 'py2neo.neo4j.Node'>
# Welcome to the Real World

Graph_tool 's find_vertex() raises a Exception

I generate a graph with the word of a sentence as tokens and dependency relations as edges.
This info comes from a external Tool in the format of ((word, index), (word, index), relation) tuple. Each word can have many dependencies and I want only one node per word.
When I process each dependency I want to search it by their ID, but when i Try to use find_vertex() i get the next Exception:
TypeError: No registered converter was able to extract a C++ reference to type graph_tool::GraphInterface from this Python object of type Graph
This is the code:
def graph(self, sentence, sentenceNamespace="sentence", separator="_"):
graph = Graph()
root_node = graph.add_vertex()
# Create a link to Root Node
graph.graph_properties['root'] = graph.new_graph_property("python::object", root_node)
# Create Node's properties
graph.vertex_properties['id'] = graph.new_vertex_property("string")
graph.vertex_properties['form'] = graph.new_vertex_property("string")
graph.vertex_properties['ord'] = graph.new_vertex_property("int64_t")
# Create edge's properties
graph.edge_properties['type'] = graph.new_edge_property("string")
# Create the root node
graph.vertex_properties['form'][root_node] = "S"
graph.vertex_properties['ord'][root_node] = -1
# Find or create the dependant and governor nodes and link with a new edge
for dependency in self.dependency(sentence):
dependency_governor = dependency[0]
# Governor's generated ID
governor_name = "{1}{0}{2[0]}{0}{1[1]}".format(separator, sentenceNamespace,dependency_governor )
dependency_dependant = dependency[1]
# Dependant's generated ID
dependant_name = "{1}{0}{2[0]}{0}{1[1]}".format(separator, sentenceNamespace, dependency_dependant)
# Relation Type
relation = dependency[2]
# This is the problematic Line ################################################
governor = find_vertex(graph, graph.vertex_properties['id'], governor_name)
##############################################################
# If search is successful use the first node else create a new one
if governor :
governor = governor[0]
else:
governor = graph.add_vertex()
graph.vertex_properties['id'][governor] = governor_name
graph.vertex_properties['form'][governor] = dependency_governor[0]
graph.vertex_properties['ord'][governor] = dependency_governor[1]
dependant = find_vertex(graph, 'id', dependant_name)
# If search is successful use the first node else create a new one
if dependant :
dependant = dependant[0]
else:
dependant = graph.add_vertex()
graph.vertex_properties['id'][dependant] = dependant_name
graph.vertex_properties['form'][dependant] = dependant_dependant[0]
graph.vertex_properties['ord'][dependant] = dependency_dependant[1]
# Link the nodes with the new dependency relation
dependency_edge = graph.add_edge(governor, dependant)
graph.edge_properties['type'][dependency_edge]= relation
return graph
This bug has been fixed in the git version.

Categories