在项目之间移动数据

本页面介绍如何使用托管式导入和导出功能将 Firestore 数据从一个项目移动到另一个项目。如果您要设置开发环境或将应用永久迁移到另一个项目,此功能就非常有用。本页面上的示例演示了如何从源项目导出数据,然后将该数据导入目标项目中。在项目之间移动数据的过程包括以下步骤:

  1. 创建 Cloud Storage 存储分区以保存源项目中的数据。
  2. 将数据从源项目导出到存储分区。
  3. 为目标项目授予从存储分区读取数据的权限。
  4. 将数据从存储分区导入目标项目中。

准备工作

您必须先完成以下任务,才能使用代管式导出和导入服务:

  1. 同时为源项目和目标项目启用结算功能。只有启用了结算功能的 Google Cloud 项目才能使用导出和导入功能。
  2. 确保您的帐号在源项目和目标项目中拥有必要的 IAM 权限。如果您是这两个项目的所有者,那么您的帐号将具有所需权限。如果不是,以下 IAM 角色可授予 Firestore 导出和导入操作所需的权限:

    OwnerCloud Datastore OwnerCloud Datastore Import Export Admin

    项目所有者可以按照授予访问权限中的步骤授予其中一个角色。

  3. 设置 gcloud 命令行工具并通过以下任一方式关联到您的项目:

从源项目导出数据

要导出数据,请为您的 Firestore 导出文件创建 Cloud Storage 存储分区并开始导出操作。

创建 Cloud Storage 存储分区

在 Firestore 数据库所在的位置创建 Cloud Storage 存储分区。要查看数据库位置,请参阅项目位置设置。您不能使用“请求者付款”存储分区执行导出和导入操作。

如果您的 Cloud Storage 存储分区不在源项目中,您必须为源项目授予对该存储分区的默认服务帐号权限。每个 Google Cloud 项目都有一个自动创建的默认服务帐号,名称为 PROJECT_ID@appspot.gserviceaccount.com。Firestore 导出操作使用此默认服务帐号对 Cloud Storage 存储分区操作进行授权。如需向此默认服务帐号授予对源存储分区的访问权限,请为其授予 Storage Admin 角色。

您可以使用 Cloud Shell 中提供的 gsutil 工具授予此角色:

启动 Cloud Shell

gsutil iam ch serviceAccount:[SOURCE_PROJECT_ID]@appspot.gserviceaccount.com:admin \
gs://[BUCKET_NAME]

您还可以在 Google Cloud Console 中授予此角色

停用写入操作(可选)

如果您的应用在您执行导出操作时继续写入数据库,则您可能无法在导出文件中捕获所有这些写入操作。要在一致的状态下导出数据,请停用写入数据库,方法是更新您的安全规则并停止所有 Admin SDK 操作。

  1. 更新安全规则

    在控制台的 Firestore 规则标签页中,更新您的源项目安全规则以拒绝所有写入操作。例如:

      // Deny write access to all users under any conditions
      service cloud.firestore {
        match /databases/{database}/documents {
          match /{document=**} {
            allow write: if false;
          }
          // Reads do not affect export operations
          // Add your read rules here
        }
      }
    
  2. 停止 Admin SDK 的写入操作

    安全规则不会停止来自特权服务器环境(使用 Firebase Admin SDKGoogle Cloud 服务器客户端库创建)的写入操作。确保通过关闭或更新您的服务器来停止来自管理服务器的写入操作。

开始导出操作

使用 gcloud firestore export 命令可导出源项目中的数据。您可以导出所有数据或仅导出特定集合。将 [SOURCE_BUCKET] 替换为您的 Cloud Storage 存储分区的名称:

导出所有数据
gcloud firestore export gs://[SOURCE_BUCKET] --async
导出特定集合
gcloud firestore export gs://[SOURCE_BUCKET] --collection-ids=[COLLECTION_ID_1],[COLLECTION_ID_2] --async

记下导出操作的 outputURIPrefix,稍后您将用到此前缀。默认情况下,Firestore 会根据时间戳为导出文件添加前缀:

outputUriPrefix: gs://[SOURCE_BUCKET]/2019-03-05T20:58:23_56418

在导出操作运行时,您可以使用 firestore operations list 命令查看操作的进度:

gcloud firestore operations list

将数据导入目标项目

接下来,为目标项目授予对 Firestore 数据文件的访问权限并启动导入操作。

为目标项目授予对数据文件的访问权限

在开始导入操作之前,您必须确保目标项目可以访问 Firestore 数据文件。

将数据文件移动到本地存储分区

如果源存储分区的位置与目标项目的 Firestore 位置不同,您必须将数据文件移动到目标项目所在位置的 Cloud Storage 存储分区中。

按照移动和重命名存储分区中的步骤将数据文件移动到另一个 Cloud Storage 存储分区。 对于以下所有步骤,请将这个新存储分区用作 [SOURCE_BUCKET]

授予项目服务帐号对源存储分区的访问权限

如果源存储分区不在目标项目中,您必须向目标项目的默认服务帐号授予对源存储分区的访问权限。默认服务帐号名为 [DESTINATION_PROJECT_ID]@appspot.gserviceaccount.com。如需向此默认服务帐号授予对源存储分区的访问权限,请为其授予 Storage Admin 角色。

您可以使用 Cloud Shell 中提供的 gsutil 工具授予此角色:

启动 Cloud Shell

gsutil iam ch serviceAccount:[DESTINATION_PROJECT_ID]@appspot.gserviceaccount.com:admin \
gs://[SOURCE_BUCKET]

您还可以在 Google Cloud Console 中授予此角色

开始导入操作

在开始执行导入操作之前,请确保为正确的项目配置了 gcloud

gcloud config set project [DESTINATION_PROJECT_ID]

使用 gcloud firestore import 命令可将源存储分区中的数据导入目标项目中:

gcloud firestore import gs://[SOURCE_BUCKET]/[EXPORT_PREFIX] --async

其中,[EXPORT_PREFIX] 与导出操作的 outputUriPrefix 中的前缀匹配。例如:

gcloud firestore import gs://[SOURCE_BUCKET]/2019-03-05T20:58:23_56418 --async

在导出操作运行时,您可以使用 firestore operations list 命令查看操作的进度:

gcloud firestore operations list