我正在使用anom来映射GAE数据存储区实体。我正在寻找一种可扩展的方法来实现对属性的唯一约束。
到目前为止,在创建这样的新记录之前,我正在检查查询
class User(Model):
...
email_id = props.String(indexed=True)
...
def pre_put_hook(self):
if (not self.id_or_name) and (User.query().where(User.email_id == self.email_id).count() > 0):
raise IntegrityError(f'Duplicate entry: User.email == {self.email_id}')
它不处理竞争条件,也不会在数据库级别上强制唯一性。没有任何比赛条件,有没有办法做到这一点?
答案 0 :(得分:2)
除了使用'email'作为您的主键do用户之外,没有什么好方法可以在数据库级别进行操作。您将依靠您的Web应用程序代码/ ORM(无论是anom
还是ndb
)执行该强制操作。
查看此答案
答案 1 :(得分:1)
当前方法仍然容易出现竞争条件的原因是,(非祖先)查询结果最终始终是一致的。即使您使用祖先查询(事务中唯一允许的查询),由于数据存储区的Isolation and consistency模型,您可能仍然面临竞争条件。
正如Alex所提到的,确保唯一性的唯一方法是将属性值用作实体的键标识符(您将在pre_put_hook
方法中检查键的存在,请参见TypeError with get_or_insert) 。但是您只能对实体类型的单个属性执行此操作,尤其是对于电子邮件地址属性,这并不是一个好主意,因为很难处理电子邮件地址更改。
可能存在强制唯一性的方法,但允许出现临时/瞬态可能重复的条件,请参见ndb verify entity uniqueness in transaction。
答案 2 :(得分:0)