更新时间:2023-12-01 22:06:16
鉴于 models.py
中的这段代码:
Given this code in models.py
:
class Member(ndb.Model):
name = ndb.StringProperty()
def remove_duplicates(prop, value):
raise Exception('Duplicate')
class Club1(ndb.Model):
members = ndb.StructuredProperty(Member, repeated=True, validator=remove_duplicates)
我可以创建一个Member
实例
>m = Member(name='Alice')
用这个 Member
实例创建一个 Club1
实例会触发验证:
creating a Club1
instance with this Member
instance triggers the validation:
> c1 = models.Club1(members=[m])
Traceback (most recent call last):
<snip>
File "models.py", line 60, in remove_duplicates
raise Exception('Duplicate')
Exception: Duplicate
但是,创建一个空的 Club1
实例然后附加一个 Member
不会:这实际上是您的测试用例.
However, creating an empty Club1
instance and then appending a Member
does not: this is effectively your test case.
> c1 = models.Club1()
> c1.members.append(m)
> c1.put()
Key('Club1', 6682831673622528)
我们可以子类化ndb.StructuredProperty
并将验证放在子类中:
We can subclass ndb.StructuredProperty
and put the validation in the subclass:
class MembersStructuredProperty(ndb.StructuredProperty):
def _validate(self, value):
raise Exception('Duplicate')
class Club2(ndb.Model):
members = MembersStructuredProperty(Member, repeated=True)
使用 Member
创建一个 Club2
实例会像以前一样触发验证:
Creating a Club2
instance with a Member
triggers the validation as before:
> c2 = models.Club2(members=[m])
Traceback (most recent call last):
<snip>
File "models.py", line 56, in _validate
raise Exception('Duplicate')
Exception: Duplicate
现在附加一个 Member
然后尝试写入数据存储区也是如此:
And now so does appending a Member
and then trying to write to the Datastore:
> c2 = models.Club2()
> c2.members.append(m)
> c2.put()
Traceback (most recent call last):
<snip>
File "models.py", line 56, in _validate
raise Exception('Duplicate')
Exception: Duplicate
因此子类化 ndb.StructuredProperty
应该允许您的测试通过.
So subclassing ndb.StructuredProperty
should allow your test to pass.
我不知道为什么 ndb 的属性验证会这样,可以说这是一个错误,或者至少是未记录的行为.
正如@DanCornilescu 在评论中所观察到的,这是一个已知错误 在 SDK 中
As @DanCornilescu observes in the comments, this is a known bug in the SDK