py2neo v3 AttributeError:对象没有属性'db_exists'

时间:2017-03-12 18:50:41

标签: python-3.x neo4j py2neo

尝试使用py2neo版本3将数据导入干净的neo4j图形数据库。我已经定义了几个节点类型,如下所示似乎一切顺利 - 除了我没看到节点出现在我的neo4j浏览器中。

这是相关的导入代码;我已经验证了记录正确加载到Python变量中。

for row in data:    
    ds = DataSource()
    #   parse Source of Information column as a list, trimming whitespace
    ds.uri = list(map(str.strip, row['data_source'].split(',')))
    ds.description = row['data_source_description']
    graph.merge(ds)

但是当我尝试graph.exists(ds)时,我收回了以下一组错误/追溯:

Traceback (most recent call last):
  File "mydir/venv/lib/python3.5/site-packages/py2neo/database/__init__.py", line 1139, in exists
    return subgraph.__db_exists__(self)
AttributeError: 'DataSource' object has no attribute '__db_exists__'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File     "mydir/venv/lib/python3.5/site-packages/py2neo/database/__init__.py", line 478, in exists
    return self.begin(autocommit=True).exists(subgraph)
  File "mydir/venv/lib/python3.5/site-packages/py2neo/database/__init__.py", line 1141, in exists
    raise TypeError("No method defined to determine the existence of object %r" % subgraph)
TypeError: No method defined to determine the existence of object <DataSource uri=['my_uri']>

令我惊讶的是,我找不到另一个讨论这个问题的论坛帖子。我猜测继承自GraphObject,但there doesn't seem to be an explicit definition of a __db_exists__ property for GraphObject继承问题。事实上,我发现提到的属性的唯一地方是definition of the exists function,当它产生此错误时。

谁能看到我在这里做错了什么?

节点类定义如下:

class Content(GraphObject):             # group Person and Institution
    pass

class Person(Content):
    __primarykey__ = 'name'

    name = Property()
    in_scholar_names = Property()
#   
    mentored = RelatedTo('Person')
    mentored_by = RelatedFrom('Person', 'MENTORED')
    worked_alongside = Related('Person', 'WORKED_ALONGSIDE')
    studied_at = RelatedTo('Institution')
    worked_at = RelatedTo('Institution')
    tagged = RelatedTo('Tag')
    member_of = RelatedTo('Institution')

    last_update = RelatedTo('UpdateLog')

    def __lt__(self, other):
        return self.name.split()[-1] < other.name.split()[-1]

class Institution(Content):
    __primarykey__ = 'name'
#   
    name = Property()
    location = Property()
    type = Property()
    carnegie_class = Property()
#   
    students = RelatedFrom('Person', 'STUDIED_AT')
    employees = RelatedFrom('Person', 'WORKED_AT')
    members = RelatedFrom('Person', 'MEMBER_OF')

    last_update = RelatedTo('UpdateLog')

    def __lt__(self, other):
        return self.name < other.name


class User(GraphObject):
    __primarykey__ = 'username'

    username = Property()
    joined = Property()
    last_access = Property()
    active = Property()

    contributed = RelatedTo('UpdateLog')


class Provenance(GraphObject):          # group UpdateLog and DataSource
    pass    
# 
class UpdateLog(Provenance):
    __primarykey__ = 'id'

    id = Property()
    timestamp = Property()
    query = Property()

    previous = RelatedTo('UpdateLog', 'LAST_UPDATE')
    next = RelatedFrom('UpdateLog', 'LAST_UPDATE')
    based_on = RelatedTo('Provenance', 'BASED_ON')

    affected_nodes = RelatedFrom('Content', 'LAST_UPDATE')
    contributed_by = RelatedFrom('User', 'CONTRIBUTED')

class DataSource(Provenance):
    __primarykey__ = 'uri'

    id = Property()
    description = Property()
    uri = Property()

    source_for = RelatedFrom('UpdateLog', 'BASED_ON')


class Tag(GraphObject):
    __primarykey__ = 'name'

    name = Property()
    description = Property()

    see_also = Related('Tag')
    tagged = RelatedFrom('Content')

1 个答案:

答案 0 :(得分:1)

好的,我想我明白了。我一直在Flask的上下文中学习py2neo,其中所有这些类定义对于生成给定节点上关系的视图(网页)非常重要。

但对于我正在编写的数据导入脚本,即首先实际创建节点和关系,我需要使用'Node'和'Relationship'的vanilla类,并且只需将类型指定为关于功能的参数。上述原始代码的此更新版本不会产生任何错误,之后graph.exists(ds)会返回true

for row in data:    
    ds = Node("DataSource")
    #   parse Source of Information column as a list, trimming whitespace
    ds['uri'] = list(map(str.strip, row['data_source'].split(',')))
    ds['description'] = row['data_source_description']
    graph.merge(ds)

另外两个值得注意的发现:

  1. 我的类继承一开始就没有了,因为我应该尝试继承Node,而不是GraphObject(尽管GraphObject是继承的正确类在Flask的背景下)
  2. 对于Node类,我必须使用dict样式的属性赋值,方括号和键名称作为引用字符串;点符号在这里偏离了基础,我很惊讶我没有得到更多的错误,而且更快。