Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google应用程序引擎模型的自定义键(Python)_Python_Google App Engine_Google Cloud Datastore_Primary Key - Fatal编程技术网

Google应用程序引擎模型的自定义键(Python)

Google应用程序引擎模型的自定义键(Python),python,google-app-engine,google-cloud-datastore,primary-key,Python,Google App Engine,Google Cloud Datastore,Primary Key,首先,我对谷歌应用程序引擎还比较陌生,所以我可能在做一些愚蠢的事情 假设我有一个Foo模型: class Foo(db.Model): name = db.StringProperty() 我想使用name作为每个Foo对象的唯一键。这是怎么做到的 当我想要获取一个特定的Foo对象时,我当前会在数据存储中查询具有目标唯一名称的所有Foo对象,但查询速度很慢(另外,在创建每个新的Foo时,确保name是唯一的也是一件痛苦的事情) 一定有更好的办法 谢谢。以下是关于AppEngine数据存储

首先,我对谷歌应用程序引擎还比较陌生,所以我可能在做一些愚蠢的事情

假设我有一个Foo模型:

class Foo(db.Model):
   name = db.StringProperty()
我想使用
name
作为每个
Foo
对象的唯一键。这是怎么做到的

当我想要获取一个特定的
Foo
对象时,我当前会在数据存储中查询具有目标唯一名称的所有
Foo
对象,但查询速度很慢(另外,在创建每个新的
Foo
时,确保
name
是唯一的也是一件痛苦的事情)

一定有更好的办法


谢谢。

以下是关于AppEngine数据存储的不合格性的详细讨论:

我以前在一个项目中使用过下面的代码。只要您的密钥名所基于的字段是必需的,它就可以工作

class NamedModel(db.Model):
    """A Model subclass for entities which automatically generate their own key
    names on creation. See documentation for _generate_key function for
    requirements."""

    def __init__(self, *args, **kwargs):
        kwargs['key_name'] = _generate_key(self, kwargs)
        super(NamedModel, self).__init__(*args, **kwargs)


def _generate_key(entity, kwargs):
    """Generates a key name for the given entity, which was constructed with
    the given keyword args.  The entity must have a KEY_NAME property, which
    can either be a string or a callable.

    If KEY_NAME is a string, the keyword args are interpolated into it.  If
    it's a callable, it is called, with the keyword args passed to it as a
    single dict."""

    # Make sure the class has its KEY_NAME property set
    if not hasattr(entity, 'KEY_NAME'):
        raise RuntimeError, '%s entity missing KEY_NAME property' % (
            entity.entity_type())

    # Make a copy of the kwargs dict, so any modifications down the line don't
    # hurt anything
    kwargs = dict(kwargs)

    # The KEY_NAME must either be a callable or a string.  If it's a callable,
    # we call it with the given keyword args.
    if callable(entity.KEY_NAME):
        return entity.KEY_NAME(kwargs)

    # If it's a string, we just interpolate the keyword args into the string,
    # ensuring that this results in a different string.
    elif isinstance(entity.KEY_NAME, basestring):
        # Try to create the key name, catching any key errors arising from the
        # string interpolation
        try:
            key_name = entity.KEY_NAME % kwargs
        except KeyError:
            raise RuntimeError, 'Missing keys required by %s entity\'s KEY_NAME '\
                'property (got %r)' % (entity.entity_type(), kwargs)

        # Make sure the generated key name is actually different from the
        # template
        if key_name == entity.KEY_NAME:
            raise RuntimeError, 'Key name generated for %s entity is same as '\
                'KEY_NAME template' % entity.entity_type()

        return key_name

    # Otherwise, the KEY_NAME is invalid
    else:
        raise TypeError, 'KEY_NAME of %s must be a string or callable' % (
            entity.entity_type())
然后,您可以修改示例模型,如下所示:

class Foo(NamedModel):
    KEY_NAME = '%(name)s'
    name = db.StringProperty()
当然,在您的例子中,这可以大大简化,将
NamedModel
\uuuu init\uuuu
方法的第一行更改为如下内容:

kwargs['key_name'] = kwargs['name']

啊,这看起来很酷,但有点过分了。不管怎样,它仍然引导我走上了正确的道路,发现了我所缺少的东西:关于key_name的知识!这是一切的关键:-)哈哈哈,我很高兴我至少为你指出了正确的方向。如果正在创建的模型实例已经有了一个键,例如在查询结果集中,会发生什么。我的理解是,除了第一次在数据存储中创建实体时被调用外,该实体的init函数还将在任何时候创建该类的实例时被调用。