如何在 Google App Engine 中为模型定义唯一属性? [英] How do I define a unique property for a Model in Google App Engine?

查看:29
本文介绍了如何在 Google App Engine 中为模型定义唯一属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一些独特的属性.我怎样才能做到这一点?

I need some properties to be unique. How can I achieve this?

有没有类似 unique=True 的东西?

Is there something like unique=True?

我使用的是 Google App Engine for Python.

I'm using Google App Engine for Python.

推荐答案

没有用于确保值唯一的内置约束.但是,您可以这样做:

There's no built-in constraint for making sure a value is unique. You can do this however:

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 因为它会通过不获取实体的数据来稍微提高性能.

I use keys_only=True because it'll improve the performance slightly by not fetching the data for the entity.

一个更有效的方法是使用一个单独的模型,没有字段的键名称由属性名称 + 值组成.然后您可以使用 get_by_key_name 来获取这些组合键名中的一个或多个,如果您获得一个或多个 not-None 值,您就知道存在重复值(并检查哪些值不是 None,你就会知道哪些不是唯一的.)

A more efficient method would be to use a separate model with no fields whose key name is made up of property name + value. Then you could use get_by_key_name to fetch one or more of these composite key names and if you get one or more not-None values, you know there are duplicate values (and checking which values were not None, you'll know which ones were not unique.)

正如评论中提到的onebyone,这些方法–由他们先得到,后放自然-ndash;运行风险并发问题.理论上,可以在检查现有值后立即创建实体,然后检查后的代码仍然会执行,导致重复值.为了防止这种情况,您必须使用交易:交易 - Google App Engine

As onebyone mentioned in the comments, these approaches – by their get first, put later nature – run the risk concurrency issues. Theoretically, an entity could be created just after the check for an existing value, and then the code after the check will still execute, leading to duplicate values. To prevent this, you will have to use transactions: Transactions - Google App Engine

如果您要检查具有事务的所有 实体的唯一性,则必须使用第一种方法将所有实体放在同一组中,这将非常低效.对于交易,使用第二种方法:

If you're looking to check for uniqueness across all entities with transactions, you'd have to put all of them in the same group using the first method, which would be very inefficient. For transactions, use the second method like this:

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(...) 将假设每个单独的键/值对必须是唯一的才能返回成功.事务将为每个模型类型使用单个实体组.这样一来,事务同时对多个不同的字段是可靠的(仅对于一个字段,这会简单得多.)此外,即使您在一个或多个模型中具有相同名称的字段,它们也不会与彼此.

UniqueConstraint.check(...) will assume that every single key/value pair must be unique to return success. The transaction will use a single entity group for every model kind. This way, the transaction is reliable for several different fields at once (for only one field, this would be much simpler.) Also, even if you've got fields with the same name in one or more models, they will not conflict with each other.

这篇关于如何在 Google App Engine 中为模型定义唯一属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆