I am using the below code in Python to try connect to Neo4j. However, when I run the code I get the error: "py2neo.database.status.Forbidden: No write operations are allowed on this database. This is a read only Neo4j instance.".
Does anyone know how I can create a write instance to Neo4j from py2neo?
import py2neo
from py2neo import Node, Relationship
g = py2neo.Graph('bolt://neo4j.het.io:7687', bolt=True)
tx = g.begin()
a = Node("Person", name="Alice")
tx.create(a)
b = Node("Person", name="Bob")
ab = Relationship(a, "KNOWS", b)
tx.create(ab)
tx.commit()
g.exists(ab)
neo4j.het.io:7687 is a public, read only Neo4j instance.
Go to https://neo4j.com/download/ and download your own database, and change your script to hit localhost:7687 instead.
(If you want that specific dataset, it is available for free -> https://github.com/dhimmel/hetionet)
Related
I have a list of gene names genes_list and a list of genes that target other genes (list of tuples) genes2, I successfully connected to my local database and created the 20244 nodes labeled GEN with name property.
I am trying to generate a script that automates the creation of relationships for any pair of nodes(usin variables tupla[0]and tupla[1]) in a Neo4j graph but I can't get the for loop to work for a list of tuples, any advice? Im still learning how to use this library any advices would be great! regards!
from py2neo import Node,Relationship,Graph, database,NodeMatcher
import time
import pandas as pd
genes_list=pd.read_csv("Gen_list.txt",delimiter="\t",header=None)
genes_list=genes_list[0].tolist()
for name in genes_list:
graph.run("CREATE(:GEN{name:$name})",name=name)
genes=pd.read_csv(r"C:\Users\espin\OneDrive\Escritorio\MCI\SCRIPTS\dorothea_final.csv", delimiter="\t",header=None)
genes2=list(genes.to_records(index=False))
for tupla in genes2:
existing_u1 = matcher.match("GEN").where(name=tupla[0]).first()
existing_u2 = matcher.match("GEN").where(name=tupla[1).first()
graph.merge(existing_u1,"REGULATES", existing_u2)
I figured out, For the people that want to try this implementation and is using py2neo V4, try using graph.run()
for tupla in genes2:
graph.run("MATCH(a:GEN{name:$name}) MATCH(b:GEN{name:$name1}) CREATE (a)-[:REGULATES]->(b)",name=tupla[0],name1=tupla[1])
remember that the query has to be in the first argument and then you declare the $variables separated by ","
at less this works when you have already created the nodes and does not duplicate the existing ones.
I have written some code with python to obtain the list of my followers and following users in Twitter. Once I have this information, I create nodes and relationships in neo4j with py2neo by looping over the list of followers and following users that I obtained.
The code seems to work fine, however not all nodes and relationships are created. I am trying to generate about 170 nodes, however only around 25 are created.
I am wondering if there is any kind of connection limit, of uploading threshold or any other thing that might be creating the problem.
I am using Python 3.6, py2neo 3.1.2 and neo4j Community distribution 3.1.3.
I am not a python expert, so please forgive my code:
import py2neo
from py2neo import Graph
from py2neo import Node, Relationship
from py2neo import authenticate
import tweepy
import time
auth = tweepy.OAuthHandler('...', '...')
auth.set_access_token('...', '...')
api = tweepy.API(auth, wait_on_rate_limit=True, wait_on_rate_limit_notify=True)
user = api.get_user(myUser)
def getFollowers(user_screen_name):
follower_ids=[]
for page in tweepy.Cursor(api.followers, screen_name=user_screen_name).pages():
time.sleep(60)
follower_ids.extend(page)
return follower_ids
def getFollowing(user_screen_name):
following_ids=[]
for page in tweepy.Cursor(api.friends, screen_name=user_screen_name).pages():
time.sleep(60)
following_ids.extend(page)
return following_ids
def createNode(screen_name):
node=Node("User", screen_name=screen_name)
gf.merge(node)
return
def createRelationship(nodeA, nodeB, relationship):
#creates relationship and nodes (if not existant)
nodeA=Node("User", screen_name=nodeA)
nodeB=Node("User", screen_name=nodeB)
gf.merge(nodeA)
gf.merge(nodeB)
gf.merge(Relationship(nodeA, relationship, nodeB))
return
authenticate("localhost:7474",myID,myPass)
gf = Graph()
#First time graph is created
gf.run("CREATE CONSTRAINT ON (u:User) ASSERT u.screen_name IS UNIQUE")
createNode(myUser)
user_followers=getFollowers(myUser)
user_following=getFollowing(myUser)
for followers in user_followers:
createRelationship(followers.screen_name, sc, "FOLLOWS")
i=1
for following in user_following:
createRelationship(sc, following.screen_name, "FOLLOWS")
I cannot think of any reason why did would not work, but I believe it is more a problem related to neo4j than the code itself.
Any help would be very much appreciated,
Thanks in advance
I am using Py2neo 3.0 and Neo4j 3.0 to create nodes. Followed the transaction statements to create the nodes but failed.
Syntax:
tx = graph.begin()
a= Node("Person1", name="Alicedemo")
tx.create(a)
tx.commit
And, then did the same without transaction, and succeeded.
Syntax:
a= Node("Person1", name="Alicedemo")
graph.create(a)
Is their any problem with transaction in py2neo or else I am missing anything there?
I believe you forgot to use parenthesis
tx.commit()
I am using py2neo with transactions. This means I am using the Cypher language. I am appending the textual Cypher statements to a transaction queue and submitting the contents of the queue in one shot with commit.
It works fine. However, it is slow. I am getting about 100/nodes per second and as the transaction queue gets larger the inserts take longer. My app times out if a transaction has more than about 6,000 nodes (and a like amount of relationships).
For now I want to focus on my Cypher. My app generates a lot of this:
CREATE (n:METHOD {version: 6995, unique: 682, return_type: 0, fully_qualified_name: 0, name: "method4", accessibility: 0})
CREATE (n:PARAMETER {version: 6995, unique: 687, fully_qualified_name: 0, param_type: 1, name: "param4", accessibility: 0})
MATCH (a:METHOD), (b:PARAMETER) WHERE a.unique=682 AND a.version=6995 AND b.unique=687 AND b.version=6995 CREATE (a)-[r:INVOKED_WITH]->(b)
So I create a METHOD node, create a PARAMETER node, then relate them. What is bothering me is that I basically create the two nodes, then throw away the fact that I just created them. Then I find them with a lookup so I can connect them. This irks me. The previous version did not use transactions; when I created a node, I got an native neo4j ID back and used that when creating relations. Now I can't do that since the textual statements are being submitted en masse to the neo4j server.
Am I allowed to put RETURN statements in there the way I can do in the neo4j web interface? Is there better Cypher to use?
EDIT - I have indexes on the "unique" property of all relevant node types.
I am not using parameters in my Python code because the code is using transactions. Therefore I have to use py2neo's mechanism to talk to neo4j directly. This involves creating the textual commands you see above.
Py2neo supports transactions and of course you can use parameters in the cypher queries, a simple code I just tested :
from py2neo import Graph
import time
graph = Graph("http://neo4j:password#localhost:7474/db/data/");
tx = graph.cypher.begin()
for x in range(0,100):
tx.append("CREATE (m:Method {id:{id}})", {"id": x})
tx.append("CREATE (p:Parameter {id:{id}})", {"id": x})
tx.append("MATCH (m:Method {id:{mid}}), (p:Parameter {id: {pid}}) CREATE (m)-[:RELATES]->(p)", {"mid": x, "pid": x})
mstart = int(round(time.time() * 1000))
tx.commit()
mend = int(round(time.time() * 1000))
diff = mend - mstart
print diff
The diff time is around 80ms
Update, you can also do:
tx.append("CREATE (m:Method {id:{method_id}}) WITH m
UNWIND {parameter_ids} as p_id
CREATE (p:Parameter {id:p_id})
CREATE (m)-[:RELATES]->(p)",
{"method_id": 1234, "parameter_ids":range(0,100)})
I'm trying to make a social network and its my first web experience.
I'm using Neo4j database and py2neo module.
Now I want to find a node from my database and change some of it's properties.
I'm using the code below,and i can run it with no errors .but it doesn't change anything in my database and i have no idea why...
please help me if you can.
from py2neo import Graph
graph=Graph()
def edit_name(Uname,name):
person=graph.merge_one("Person","username",Uname)
person.cast(fname=name)
Cast is for casting general Python objects to py2neo objects. For example, if you wanted to cast a Python dictionary to a py2neo Node object, you'd do:
from py2neo import Graph, Node
graph = Graph()
d = {'name':'Nicole', 'age':24}
nicole = Node.cast('Person', d)
However, you still need to pass nicole to Graph.create to actually create the node in the database:
graph.create(nicole)
Then, if you later retrieve this node from the database with Graph.merge_one and want to update properties:
nicole = graph.merge_one('Person', 'name', 'Nicole')
nicole['hair'] = 'blonde'
Then you need to push those changes to the graph; cast is inappropriate for updating properties on something that is already a py2neo Node object:
nicole.push()
TL;DR:
from py2neo import Graph
graph = Graph()
def edit_username(old_name, new_name):
person = graph.merge_one('Person', 'username', old_name)
person['username'] = new_name
person.push()
merge_one will either return a matching node, or, if no matching node exists, create and return a new one. So, in your case, a matching node probably already exists.