创建、检索、更新和删除实体

Datastore 中的数据对象称为“实体”,其中的每个实体都会出于查询目的而归类为特定“种类”。例如,如果您要编写人力资源应用,则可以使用种类为 Employee 的实体表示每位员工。请注意,实体数据值采用属性形式。 如需详细了解实体,请参阅有关祖先路径事务的文档。

创建实体并设置属性

您可以通过为其模型类调用构造函数方法来创建实体并进行设置。如需了解有关创建实体模型类的信息,请参阅创建和使用实体模型类

以下示例显示如何使用关键字参数调用模型类构造函数:

sandy = Account(
    username='Sandy', userid=123, email='sandy@example.com')

此代码在程序的主内存中创建一个对象。但请注意,该实体在进程终止时会消失,因此您还必须通过调用 put() 将实体永久保存到 Datastore,如下所示:

sandy_key = sandy.put()

请注意,这将返回一个键,您稍后可以使用该键从 Datastore 检索实体

请使用以下任一选项设置属性:

  • 利用关键字参数为构造函数指定实体的属性:
    sandy = Account(
        username='Sandy', userid=123, email='sandy@example.com')
  • 创建实体后手动设置属性:
    sandy = Account()
    sandy.username = 'Sandy'
    sandy.userid = 123
    sandy.email = 'sandy@example.com'
  • 使用 populate() 便捷方法在一个操作中设置多个属性:
    sandy = Account()
    sandy.populate(
        username='Sandy',
        userid=123,
        email='sandy@gmail.com')

不论您如何选择设置实体的属性,属性类型(在本例中为 StringPropertyIntegerProperty)都会强制执行类型检查。

例如:

bad = Account(
    username='Sandy', userid='not integer')  # raises an exception
...
sandy.username = 42  # raises an exception

从键中检索实体

如果您知道实体的键,则可以从 Datastore 中检索该实体:

sandy = sandy_key.get()

Key 方法 kind()id() 从键中恢复实体的种类和标识符:

kind_string = sandy_key.kind()  # returns 'Account'
ident = sandy_key.id()  # returns '2'

您还可以使用实体的键来获取适合嵌入网址的编码字符串:

url_string = sandy_key.urlsafe()

这会产生类似于 agVoZWxsb3IPCxIHQWNjb3VudBiZiwIM 的结果,之后可以用它来重新构造键和检索原始实体:

sandy_key = ndb.Key(urlsafe=url_string)
sandy = sandy_key.get()

请注意,网址安全字符串看起来已加密,但实际未加密!它可以被轻易解码以恢复原始实体的种类和标识符:

key = Key(urlsafe=url_string)
kind_string = key.kind()
ident = key.id()

如果您使用此类网址安全键,请不要将敏感数据(如电子邮件地址)用作实体标识符。可能的解决方案是使用敏感数据的哈希值作为标识符。 这会阻止可以查看加密密钥的第三方使用它们来收集电子邮件地址,但这并不能阻止他们自行独立针对已知电子邮件地址生成自己的哈希值,并使用它来检查 Datastore 中是否存在该地址。

更新实体

如需更新现有实体,请从 Datastore 检索它,修改其属性,然后再将其重新存储到数据存储区中:

sandy = key.get()
sandy.email = 'sandy@example.co.uk'
sandy.put()

在这种情况下,您可以忽略由 put() 返回的值,因为在您进行更新时实体键不会更改。

删除实体

当不再需要实体时,您可以使用键的 delete() 方法将其从 Datastore 中移除:

sandy.key.delete()

请注意,这是对键的操作,而不是对实体本身的操作。它始终返回 None

批量删除实体

如果您需要删除大量实体,我们建议您使用 Dataflow 批量删除实体

使用批量操作

您可以在单个调用中处理实体或键的集合,而不是通过不同的调用来逐个处理,例如在循环内。这使得可以对批处理操作执行单个远程过程调用 (RPC),而不是对每个实体执行单独的 RPC 调用。

以下代码显示了如何执行此操作:

list_of_keys = ndb.put_multi(list_of_entities)
list_of_entities = ndb.get_multi(list_of_keys)
ndb.delete_multi(list_of_keys)

在上面的代码中,您将键对象列表传递给 ndb.get_multi 以批量获取多个实体;ndb.get_multi 返回实体对象列表,对于在 Datastore 中没有对应实体的键,返回 None 值。采用这种方式获取实体可以减少整个批处理操作调用 Datastore 的次数。(每个批处理操作的调用次数取决于批次大小设置。)