有没有办法使用 Python3(没有数据流)从数据存储命名空间中删除所有实体?

Is there a way to delete all entities from a Datastore namespace Using Python3 (WITHOUT Dataflow)?

在测试期间上传测试数据之前需要擦除数据存储命名空间。将 Cloud Datastore API 与 Python3.

结合使用

我在 Python3 中将 Datastore 与 App Engine 结合使用。出于测试目的,我使用云数据存储 API 编写了一个脚本,用于将多个不同类型的实体上传到数据存储。由于这是一个小项目,目前只有4种,每种只有2-3个实体。

我想向我的管道添加一个脚本,以清除 Datastore 中将包含我的测试数据的特定命名空间。我希望在上传数据和测试之前 运行 这样测试每次都可以从头开始。在部署到 App Engine 之前,我正在使用 Cloud Builder 将实体上传到数据存储和 运行 我在 docker 容器中的测试。

目前我能找到的唯一解决方案是使用数据流(我认为这完全是矫枉过正),或者使用它的键单独删除每个实体。如果可能的话,我宁愿只擦除整个命名空间。

如果有人对此有任何意见或建议,请告诉我!

您可以在python中编写脚本来删除特定命名空间中的所有种类。 假设您事先知道种类的名称。

from google.appengine.ext import ndb
from google.appengine.api import namespace_manager

namespace = "PROVIDE_NAMESPACE_HERE"
kind_list = [kind_1,kind_2,kind_3,kind_4]

namespace_manager.set_namespace(namespace) # will set to the namespace provided

for a_kind in kind_list:
    # will fetch keys of all objects in that kind
    kind_keys = a_kind.gql("").fetch(keys_only = True) 
    # will delete all the keys at once
    ndb.delete_multi(kind_keys) 

从特定命名空间中删除所有种类后,您的命名空间将在 Cloud Datastore 中显示大约 24 小时,如果之后它不包含任何种类,它将被自动删除。

希望这能回答您的问题!!

应该能够使用与您的应用相同的云数据存储API,甚至可以从 Google 云外部使用(请参阅How do I use Google datastore for my web app which is NOT hosted in google app engine?)。这个答案仅基于文档,我没有实际尝试过。

您需要按照以下方式做一些事情:

  1. 在您的应用程序的数据存储区中找到所有种类(也许只是在感兴趣的命名空间中?)。这可以使用数据存储 metadata, in particular Kind queries:

    query = client.query(kind='__kind__')
    query.keys_only()
    
    kinds = [entity.key.id_or_name for entity in query.fetch()]
    
  2. 找到每种实体的键,使用您现在知道的常规键查询。将这些查询限制在感兴趣的名称空间内。按键删除实体,批量删除更高效:

    for kind in kinds:
        query = client.query(kind=kind, namespace=NAMESPACE)
        query.keys_only()
        keys = query.fetch()
        client.delete_multi(keys)
    

对于 Python 3 中的 App Engine,您应该使用 Google Cloud Client Library for Python

您还必须为管道设置数据存储身份验证。请参阅 https://cloud.google.com/datastore/docs/reference/libraries 了解如何添加 GOOGLE_APPLICATION_CREDENTIALS 环境变量。

删除所有测试数据的步骤

导入数据存储库

from google.cloud import datastore

创建数据存储客户端

ds_client = datastore.Client()

查询测试数据中的所有实体

query = ds_client.query(kind="Testdata")

从查询 fetch 创建列表

entities = list(query.fetch())

现在您可以遍历列表并删除所有数据:

for entity in entities:
    ds_client.delete(entity.key)

下面是创建一些测试数据然后从测试数据命名空间中删除所有实体的完整示例:

from google.cloud import datastore


def create_some_test_data():
    """Function for Creating Test data"""

    kind = 'Testdata'
    number_of_entities = 10

    ds_client = datastore.Client()

    print('-- Creating test data --')

    for i in range(number_of_entities):
        key = ds_client.key(kind)
        entity = datastore.Entity(key=key)
        entity.update({'test_data': i})
        ds_client.put(entity)
        print('Creating entity: {}'.format(entity))


def delete_all_test_data():
    """Function for Deleting all the Test data"""

    kind = 'Testdata'

    ds_client = datastore.Client()
    fetch_limit = 100

    print('-- Deleting all entities --')

    entities = True
    while entities:
        query = ds_client.query(kind=kind)
        entities = list(query.fetch(limit=fetch_limit))
        for entity in entities:
            print('Deleting: {}'.format(entity))
            ds_client.delete(entity.key)


# Execute the functions
create_some_test_data()
delete_all_test_data()

运行 该示例应输出如下内容:

-- Creating test data --
Creating entity: <Entity('Testdata', 5664747265458176) {'test_data': 0}>
Creating entity: <Entity('Testdata', 5723707007827968) {'test_data': 1}>
Creating entity: <Entity('Testdata', 5748214695198720) {'test_data': 2}>
Creating entity: <Entity('Testdata', 5683780991844352) {'test_data': 3}>
Creating entity: <Entity('Testdata', 5742950029983744) {'test_data': 4}>
Creating entity: <Entity('Testdata', 5716561121771520) {'test_data': 5}>
Creating entity: <Entity('Testdata', 5148025362055168) {'test_data': 6}>
Creating entity: <Entity('Testdata', 5729450050191360) {'test_data': 7}>
Creating entity: <Entity('Testdata', 5079111831650304) {'test_data': 8}>
Creating entity: <Entity('Testdata', 5681150794137600) {'test_data': 9}>
-- Deleting all entittes --
Deleting: <Entity('Testdata', 5079111831650304) {'test_data': 8}>
Deleting: <Entity('Testdata', 5148025362055168) {'test_data': 6}>
Deleting: <Entity('Testdata', 5664747265458176) {'test_data': 0}>
Deleting: <Entity('Testdata', 5681150794137600) {'test_data': 9}>
Deleting: <Entity('Testdata', 5683780991844352) {'test_data': 3}>
Deleting: <Entity('Testdata', 5716561121771520) {'test_data': 5}>
Deleting: <Entity('Testdata', 5723707007827968) {'test_data': 1}>
Deleting: <Entity('Testdata', 5729450050191360) {'test_data': 7}>
Deleting: <Entity('Testdata', 5742950029983744) {'test_data': 4}>
Deleting: <Entity('Testdata', 5748214695198720) {'test_data': 2}>