截至 2020 年,虽然使用All Іѕ Vаиітyneomodel 4.0.1
的回答并不会产生预期的结果。因此,来自user3280193的答案是最正确的,但并非没有一点警告,所以让我详细说明一下。
标签黑客(不推荐!)
首先让我们看看为什么标签黑客有缺陷:
class Unemployed(StructuredNode):
__label__ = 'Person:Unemployed'
name = StringProperty(unique_index=True)
Unemployed(name='Carol').save()
如果您检查,即使它们已正确保存在数据库中,它也无法在以后正确检测节点:
print(len(Unemployed.nodes)) # prints 0
人们可能会认为,如果我们有另一个类Person
,那么我们可以这样检索它——不幸的是不是。你自己看:
class Unemployed(StructuredNode):
__label__ = 'Person:Unemployed'
name = StringProperty(unique_index=True)
class Person(StructuredNode):
name = StringProperty(unique_index=True)
Unemployed(name='Carol').save()
到目前为止,一切都很好,所以让我们尝试获取一些节点。下面的结果看起来不错。
print(len(Person.nodes)) # prints 1
但是,当我们尝试访问该节点时会出现问题:
print(Person.nodes[0])
# Results in two exceptions
#
# Traceback (most recent call last):
# ...
# KeyError: frozenset({'Person', 'Unemployed'})
#
# During handling of the above exception, another exception occurred:
# ...
# neomodel.exceptions.ModelDefinitionMismatch: <exception str() failed>
我不会详细说明为什么会发生这种情况,但简单地说,neomodel 无法应对标签黑客攻击,因为它不是为它设计的。如果有人想了解这种行为,我建议查看neomodel.core
图书馆的一部分。
遗产
官方上,neomodel 提倡继承和混合。阅读更多:
https://neomodel.readthedocs.io/en/latest/extending.html#inheritance
https://neomodel.readthedocs.io/en/latest/extending.html#mixins
由于mixins 不提供额外的标签,我将重点介绍继承。让我们假设以下示例,其中我们深入到 2 级继承。
class Person(StructuredNode):
name = StringProperty(unique_index=True)
class Student(Person):
pass
class Employed(Person):
pass
class EmployedStudent(Student, Employed):
pass
Person(name='Bob').save()
Student(name='Will').save()
Employed(name='John').save()
EmployedStudent(name='Kim').save()
结果:
print(len(Person.nodes)) # 4
print(len(Student.nodes)) # 2
print(len(Employed.nodes)) # 2
print(len(EmployedStudent.nodes)) # 1
这具有正确的行为,但似乎产生了一种人工制品 - 标签EmployedStudent
。摆脱这个额外的标签没有简单的技巧,因为它对于自动类解析至关重要。
结论:OGM 有其缺点,但我会随时选择额外的冗余标签,而不是自己为我构建的每个类编写密码查询。