在Jupyter Notebook中运行py2neo语句时出现AttributeError和ValueError

问题描述

在尝试创建唯一约束或简单合并语句时接收AttributeErrorValueError。但是约束/节点是在Neo4j数据库中创建的。

我正在使用py2neo==2020.0.0

## Create uniqueness constraint (with name)
cypher_str = "CREATE CONSTRAINT UniqueAirportNameConstraint ON (a:Airport) ASSERT a.name IS UNIQUE"
graph.run(cypher_str)

## Merging
params = [{'airline': '3K','seats': 500,'departure': '0915'}]
q = """
    UNWIND $data AS data
    MERGE (s:Schedule)
    """
graph.run(q,{ "data": params })

收到错误

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
~/miniconda3/envs/neo4j/lib/python3.7/site-packages/py2neo/database/work.py in __init__(self,records,keys)
    889             try:
--> 890                 k = records.keys()
    891             except AttributeError:

AttributeError: 'list' object has no attribute 'keys'

During handling of the above exception,another exception occurred:

ValueError                                Traceback (most recent call last)
~/miniconda3/envs/neo4j/lib/python3.7/site-packages/IPython/core/formatters.py in __call__(self,obj)
    700                 type_pprinters=self.type_printers,701                 deferred_pprinters=self.deferred_printers)
--> 702             printer.pretty(obj)
    703             printer.flush()
    704             return stream.getvalue()

~/miniconda3/envs/neo4j/lib/python3.7/site-packages/IPython/lib/pretty.py in pretty(self,obj)
    392                         if cls is not object \
    393                                 and callable(cls.__dict__.get('__repr__')):
--> 394                             return _repr_pprint(obj,self,cycle)
    395 
    396             return _default_pprint(obj,cycle)

~/miniconda3/envs/neo4j/lib/python3.7/site-packages/IPython/lib/pretty.py in _repr_pprint(obj,p,cycle)
    698     """A pprint that just redirects to the normal repr function."""
    699     # Find newlines and replace them with p.break_()
--> 700     output = repr(obj)
    701     lines = output.splitlines()
    702     with p.group():

~/miniconda3/envs/neo4j/lib/python3.7/site-packages/py2neo/database/work.py in __repr__(self)
    367 
    368     def __repr__(self):
--> 369         return repr(self.preview(3))
    370 
    371     def __next__(self):

~/miniconda3/envs/neo4j/lib/python3.7/site-packages/py2neo/database/work.py in preview(self,limit)
    497                 values = self._hydrant.hydrate(keys,values,entities=self._entities,version=v)
    498             records.append(values)
--> 499         return Table(records,keys)
    500 
    501     def evaluate(self,field=0):

~/miniconda3/envs/neo4j/lib/python3.7/site-packages/py2neo/database/work.py in __init__(self,keys)
    890                 k = records.keys()
    891             except AttributeError:
--> 892                 raise ValueError("Missing keys")
    893         width = len(k)
    894         t = [set() for _ in range(width)]

ValueError: Missing keys

解决方法

根本原因似乎是两个Cypher语句都没有返回值,由于某种原因,返回的游标(py2neo.database.work.Cursor)期望这样做。

一个简单的解决方法是将输出分配给变量,例如:

## Create uniqueness constraint (with name)
cypher_str = "CREATE CONSTRAINT UniqueAirportNameConstraint ON (a:Airport) ASSERT a.name IS UNIQUE"
response = graph.run(cypher_str)

## Merging
params = [{'airline': '3K','seats': 500,'departure': '0915'}]
q = """
    UNWIND $data AS data
    MERGE (s:Schedule)
    """
response = graph.run(q,{ "data": params })

注意:response变量可能可以用一次性var _代替。

对于MERGE语句,我们还可以通过添加RETURN 1或一些有用的东西来避免此错误。