没有用于确保值唯一的内置约束。但是,您可以这样做:
query = MyModel.all(keys_only=True).filter('unique_property', value_to_be_used)
entity = query.get()
if entity:
raise Exception('unique_property must have a unique value!')
我使用keys_only=True 是因为它会通过不为实体获取数据而略微提高性能。
更有效的方法是使用没有字段的单独模型,其键名由属性名 + 值组成。然后你可以使用get_by_key_name 来获取这些复合键名称中的一个或多个,如果你得到一个或多个 not-None 值,你就知道有重复值(并检查哪些值不是 None,你会知道哪些不是唯一的。)
正如 onebyone 在 cmets 中提到的那样,这些方法 - 按其先入为主的性质 - 存在并发问题的风险。理论上,可以在检查现有值后立即创建实体,然后检查后的代码仍将执行,从而导致重复值。为防止这种情况,您必须使用事务:Transactions - Google App Engine
如果您要检查具有交易的所有实体的唯一性,则必须使用第一种方法将所有实体放在同一个组中,这将非常低效。对于交易,使用第二种方法,如下所示:
class UniqueConstraint(db.Model):
@classmethod
def check(cls, model, **values):
# Create a pseudo-key for use as an entity group.
parent = db.Key.from_path(model.kind(), 'unique-values')
# Build a list of key names to test.
key_names = []
for key in values:
key_names.append('%s:%s' % (key, values[key]))
def txn():
result = cls.get_by_key_name(key_names, parent)
for test in result:
if test: return False
for key_name in key_names:
uc = cls(key_name=key_name, parent=parent)
uc.put()
return True
return db.run_in_transaction(txn)
UniqueConstraint.check(...) 将假定每个键/值对都必须唯一才能返回成功。该事务将为每个模型类型使用一个实体组。这样,事务同时对多个不同的字段是可靠的(仅对于一个字段,这会简单得多。)此外,即使您在一个或多个模型中具有相同名称的字段,它们也不会与彼此。