Search code examples
neo4jpy2neoneomodel

Problems using python packages (Neomodel & py2neo) with Neo4j


I am having some issues using the Neomodel and py2neo clients with Neo4j. I have installed Neomodel and py2neo in seperate anaconda virtual environments and tested each individually. Neo4j is installed/docked using docker.

Neomodel

The code

from neomodel import (config, StructuredNode, StringProperty, IntegerProperty,UniqueIdProperty, RelationshipTo, RelationshipFrom)                            

config.DATABASE_URL = 'bolt://neo4j:password@localhost:7687'                    

class Country(StructuredNode):                                                     
    code = StringProperty(unique_index=True, required=True)                        

    # traverse incoming IS_FROM relation, inflate to Person objects                
    inhabitant = RelationshipFrom('Person', 'IS_FROM')                             


class Person(StructuredNode):                                                      
    uid = UniqueIdProperty()                                                       
    name = StringProperty(unique_index=True)                                       
    age = IntegerProperty(index=True, default=0)                                   

    # traverse outgoing IS_FROM relations, inflate to Country objects              
    country = RelationshipTo(Country, 'IS_FROM')  

jim = Person(name='Jim', age=3).save()                                             
jim.age = 4                                                                        
jim.save() # validation happens here                                               
jim.delete()                                                                       
jim.refresh() # reload properties from neo                                         
jim.id # neo4j internal id  

While Neomodel generates the node viewed on the neo4j webapp. The node created is Jim with age=3 i.e. It does not seem to have recorded the fact that Jims age changed from 3 -> 4. Also, I am assuming that jim.delete() would have deleted the node which it did not neither. Lastly, it prompts the following error (below is a snippet of the last lines of the error).

Error

...
File "/Users/sjamal/.conda/envs/tneo/lib/python3.6/site- 
packages/neomodel/core.py", line 452, in inflate
if db_property in node.properties:
AttributeError: 'Node' object has no attribute 'properties'

Now I did find this post where the user "Jack Daniel" mentioned that neomodel does not support neo4j 3. So I tried docking the Neo4j v.2.3 image but then I receive the following error (note that its a snippet of the last few lines of the error)

Error when docking image Neo4j 2.3

File "/Users/sjamal/.conda/envs/tneo/lib/python3.6/ssl.py", line 817, in __init__
self.do_handshake()
File "/Users/sjamal/.conda/envs/tneo/lib/python3.6/ssl.py", line 1077, in do_handshake
self._sslobj.do_handshake()
File "/Users/sjamal/.conda/envs/tneo/lib/python3.6/ssl.py", line 689, in do_handshake
self._sslobj.do_handshake()
OSError: [Errno 0] Error

Py2neo

I started looking into using p2neo due to the issues I had with Neomodel but I cannot seem to get my configurations right.

The code

from py2neo import Node, Relationship, Graph                                       

graph = Graph("localhost", user='neo4j', password='password', bolt=None)           

alice = Node("Person", name="Alice")                                               
bob = Node("Person", name="Bob")                                                   
alice_knows_bob = Relationship(alice, "KNOWS", bob)                                
graph.create(alice_knows_bob)  

Error

File "/Users/sjamal/.conda/envs/py2neo_test/lib/python3.6/site-packages/neo4j/bolt/connection.py", line 459, in acquire
connection = self.connector(address)
File "/Users/sjamal/.conda/envs/py2neo_test/lib/python3.6/site-packages/neo4j/v1/bolt.py", line 46, in <lambda>
pool = ConnectionPool(lambda a: connect(a, security_plan.ssl_context, **config))
File "/Users/sjamal/.conda/envs/py2neo_test/lib/python3.6/site-packages/neo4j/bolt/connection.py", line 601, in connect
raise ProtocolError("Connection to %r closed without handshake response" % (address,))
neo4j.bolt.connection.ProtocolError: Connection to ('localhost', 7687) closed without handshake response

Thanks to anyone looking into this. I would be happy to receive any suggestion or explanation on how to set up Py2neo irrespective if I get Neomodel to work or not.


Solution

  • So I have managed to solve my issue with Py2neo but not the issue I had with Neomodel. If I do find a way to get Neomodel working I will post it and either link to this post or post as a comment in this thread.

    Py2neo solution with py2neo v4.0 and neo4j v3.o

    I tried various combinations, starting with neo4j 2.3 together with different versions of py2neo such as 3.1.2 and then did the same with neo4j v3.0.

    I am posting my script that I used to create the node and the graph connection as I was going mad when trying to figure out if I set up the configuration poorly or there was a bug in the package, driver etc.

    Py2neo script

    from py2neo import Node, Relationship, Graph                                       
    
    graph = Graph('http://localhost:7474/db/data',user='neo4j',pass word='password1234')
    tx = graph.begin()                                                                 
    a = Node(label='hero',name='Sabri')                                                
    tx.create(a)                                                                       
    tx.commit()  
    

    Outdated driver py2neo v3.1.2 in tandem with Neo4j v3.4

    As discussed in this Github issue report https://github.com/neo4j/neo4j-python-driver/issues/252 the user who reported the issue was using py2neo 3.1.2 together with Neo4jv3.4. The suspicion was that it was due to an outdated driver (v1.1) that came with py2neo 3.1.2. The new distribution of Neo4j v3.4 seems to come with the new driver 1.6.

    Upgrading py2neo to v4.0 and sticking to latest version of Neo4j server i.e. v3.4

    When doing this I ran into a different error

    File "/Users/sjamal/.conda/envs/py2neo.v4/lib/python3.6/site-packages/py2neo/internal/http.py", line 26, in <module>
    from neo4j.addressing import SocketAddress
    ModuleNotFoundError: No module named 'neo4j.addressing'
    

    It was discussed in this stackoverflow thread (ModuleNotFoundError: No module named 'neo4j.addressing' and ModuleNotFoundError: No module named 'neo4j') that the issue might be that the driver 1.6 driver might have to be manually installed through pip, which I did.

    pip install neo4j-driver==1.6.2
    

    I now received a new error where TypeError was caught when calling a map object.

    File "/Users/sjamal/.conda/envs/py2neo.v4/lib/python3.6/site-packages/py2neo/internal/http.py", line 74, in fix_parameters
    raise TypeError("Parameters of type {} are not supported".format(type(value).__name__))
    

    TypeError: Parameters of type map are not supported

    I found this github issue posted by speters-cmri https://github.com/technige/py2neo/issues/688 which contained the following github commit (https://github.com/technige/py2neo/compare/v4...CMRI-ProCan:v4) to resolve the issue by modifying a json.py script in the py2neo package

    I ran my script again to add a test node and it ran without any issues.

    If you are too lazy or simply too frustrated to go through a long explanation here is a summary

    1. Make sure neo4j v3.0+ is installed. I suggest you look into docker to install neo4j using a docker image
    
    2. pip install py2neo==v4.0
    3. pip install neo4j-driver==1.6.2
    
    4. Modify json.py file as described here https://github.com/technige/py2neo/compare/v4...CMRI-ProCan:v4
    
    5. Run py2neo script outlined above