Search code examples
pythonflaskneo4jpy2neo

Py2neo (V4) - AttributeError: 'Graph' object has no attribute 'find_one'


I am trying to update the neo4j-flask application to Py2Neo V4 and i could not find how the "find_one" function has been replaced. (Nicole White used Py2Neo V2)

My setup:

  • Ubuntu 18.04
  • Python 3.6.5
  • Neo4j Server version: 3.4.6 (community)

Requirements.txt (the rest of the code is from github repository by Nicole White):

atomicwrites==1.2.0
attrs==18.1.0
backcall==0.1.0
bcrypt==3.1.4
certifi==2018.8.24
cffi==1.11.5
click==6.7
colorama==0.3.9
decorator==4.3.0
Flask==1.0.2
ipykernel==4.8.2
ipython==6.5.0
ipython-genutils==0.2.0
itsdangerous==0.24
jedi==0.12.1
Jinja2==2.10
jupyter-client==5.2.3
jupyter-console==5.2.0
jupyter-core==4.4.0
MarkupSafe==1.0
more-itertools==4.3.0
neo4j-driver==1.6.1
neotime==1.0.0
parso==0.3.1
passlib==1.7.1
pexpect==4.6.0
pickleshare==0.7.4
pkg-resources==0.0.0
pluggy==0.7.1
prompt-toolkit==1.0.15
ptyprocess==0.6.0
py==1.6.0
py2neo==4.1.0
pycparser==2.18
Pygments==2.2.0
pytest==3.7.3
python-dateutil==2.7.3
pytz==2018.5
pyzmq==17.1.2
simplegeneric==0.8.1
six==1.11.0
tornado==5.1
traitlets==4.3.2
urllib3==1.22
wcwidth==0.1.7
Werkzeug==0.14.1

Error i received when register user:

AttributeError: 'Graph' object has no attribute 'find_one'

"The User.find() method uses py2neo’s Graph.find_one() method to find a node in the database with label :User and the given username, returning a py2neo.Node object. "

In Py2Neo V3 the function find_one -> https://py2neo.org/v3/database.html?highlight=find#py2neo.database.Graph.find_one is available.

In Py2Neo V4 https://py2neo.org/v4/matching.html there is not find function anymore.

Someone got an idea on how to solve it in V4 or is downgrading here the way to go?


Solution

  • py2neo v4 has a first function that can be used with a NodeMatcher. See: https://py2neo.org/v4/matching.html#py2neo.matching.NodeMatch.first

    That said... v4 has introduced GraphObjects which (so far at least) I've found pretty neat.

    In the linked github example Users are created with:

    user = Node('User', username=self.username, password=bcrypt.encrypt(password))
    graph.create(user)
    

    and found with

    user = graph.find_one('User', 'username', self.username)
    

    In py2neo v4 I would do this with

    class User(GraphObject):
        __primarykey__ = "username"
    
        username = Property()
        password = Property()
    
     lukas = User()
     lukas.username = "lukasott"
     lukas.password = bcrypt.encrypt('somepassword')
     graph.push(lukas)
    

    and

    user = User.match(graph, "lukasott").first()
    

    The first function, as I understand it, provides the same guarantees that find_one, as quoted from the v3 docs "and does not fail if more than one matching node is found."