播种数据并执行批量数据操作

Firebase Data Connect 中,您可以根据工作流程和环境,通过不同方式执行批量数据加载和更新:

  • 本地原型设计中,当您尝试替代架构时,可以使用 VS Code 扩展程序、Data Connect 模拟器和本地数据库实例在本地开发环境中创建和调用数据播种突变。

  • 生产开发中,如果架构稳定,并且您正在执行较大的 CI/CD 流程和管理生产数据,则可以选择以下两种方式:

    • 首选方法是使用 Firebase Admin SDK,这是一组在特权环境中运行的库。

    • 您还可以将 SQL 工具与 Cloud SQL 实例搭配使用,以执行批量加载和更新,前提是您要修改的是数据,而不是数据库架构。直接使用 SQL 工具修改数据库架构可能会破坏 Data Connect 架构和连接器。

本地原型设计:在本地实例中植入种子数据

使用指南中,您设置了一个应用,用于使用临时插入突变向单个表中添加单个记录。

为了能够使用,电影评价应用需要电影、评价和用户的数据,以便对使用联接和其他操作的多个表进行原型查询和突变,并使用真实数据。您可以扩展架构并为数据库植入初始数据。

您的原型设计环境需要代码来执行数据植入。本指南提供了一些示例,用于说明:

  • 在单个表中使用 _insertMany_upsertMany
  • 在相关表上使用 _insertMany

更新影评应用架构

您可以使用 _insertMany_upsertMany 变更一次更新单个数据库表,也可以更新通过联接关系关联的多个表。下面展示了一个扩展的电影评论应用架构,可帮助说明这些使用情形和示例。它将 schema.gql 从初始 Movie 类型扩展为包含 ActorMovieActor 类型,以便我们对更复杂的查询进行原型设计。

# Actors
# Suppose an actor can participate in multiple movies and movies can have multiple actors
# Movie - Actors (or vice versa) is a many to many relationship
type Actor @table {
  id: UUID!
  imageUrl: String! 
  name: String! @col(name: "name", dataType: "varchar(30)")
}

# Join table for many-to-many relationship for movies and actors
# The 'key' param signifies the primary key(s) of this table
# In this case, the keys are [movieId, actorId], the generated fields of the reference types [movie, actor]
type MovieActor @table(key: ["movie", "actor"]) {
  # @ref creates a field in the current table (MovieActor) that holds the primary key of the referenced type
  # In this case, @ref(fields: "movieId", references: "id") is implied
  movie: Movie!
  # movieId: UUID! <- this is created by the implied @ref
  actor: Actor!
  # actorId: UUID! <- this is created by the implied @ref
  role: String! # "main" or "supporting"
}

写入变更以设定初始状态数据

在原型设计期间,当您需要针对一系列离散值测试查询和突变时,可以使用多条记录填充数据。例如,您可能需要添加多个具有不同类型流派和分级的电影记录,以便进行测试比较和过滤。

将数据植入到 MovieActor 表中

根据原型设计的阶段,您可以使用“使用入门”指南中介绍的相同技术来插入一条或两条记录:也就是说,您可以使用 VS Code 扩展程序中的 CodeLens 来创建 _insert 突变、对数据进行硬编码,以及在 VS Code 中运行这些突变

最终,使用 _insertMany 操作将多个记录添加到表中会更有意义。在电影评论应用示例中,此方法会在 MovieActor 中插入一组初始数据。

如需使用 VS Code Firebase 扩展程序执行以下突变,请在相应的文件编辑器视图中点击 Run (Production)(运行 [生产])或 Run (Local)(运行 [本地])CodeLens 按钮,具体取决于您是使用生产服务还是本地数据库进行原型设计。

# insertMany for Movie
# 2 records shown
mutation {
  movie_insertMany(data: [
    {
      id: "550e8400-e29b-41d4-a716-446655440000",
      title: "Inception",
      imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Finception.jpg?alt=media&token=07b09781-b302-4623-a5c3-1956d0143168",
      genre: "sci-fi",
    },
    {
      id: "550e8400-e29b-41d4-a716-446655440001",
      title: "The Matrix",
      imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Fthe_matrix.jpg?alt=media&token=4975645d-fef8-409e-84a5-bcc1046e2059",
      genre: "action",
    }
  ])
}
# insertMany for Actor
# 2 records shown
mutation {
  actor_insertMany(data: [
    {
      id: "123e4567-e89b-12d3-a456-426614174000",
      imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fdicaprio.jpeg?alt=media&token=452e030a-efa5-4ef4-bb81-502b23241316",
      name: "Leonardo DiCaprio"
    },
    {
      id: "123e4567-e89b-12d3-a456-426614174001",
      imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fkeanu.jpg?alt=media&token=6056520c-ef3e-4823-aad0-108aab163115",
      name: "Keanu Reeves"
    }
   ])
}

将数据植入到 MovieActor 联接表中

如需测试使用联接和其他复杂操作的查询和变更,您可以向 MovieActor 表添加多条记录。

在这种关系中更新多个表时,您可以添加 @transaction 指令,以确保更新正常完成。

mutation @transaction {
  movie_insertMany(data: [
    {
      id: "550e8400-e29b-41d4-a716-446655440000",
      title: "Inception",
      imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Finception.jpg?alt=media&token=07b09781-b302-4623-a5c3-1956d0143168",
      genre: "sci-fi",
    },
    {
      id: "550e8400-e29b-41d4-a716-446655440001",
      title: "The Matrix",
      imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Fthe_matrix.jpg?alt=media&token=4975645d-fef8-409e-84a5-bcc1046e2059",
      genre: "action",
    }
  ])

  actor_insertMany(data: [
    {
      id: "123e4567-e89b-12d3-a456-426614174000",
      imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fdicaprio.jpeg?alt=media&token=452e030a-efa5-4ef4-bb81-502b23241316",
      name: "Leonardo DiCaprio"
    },
    {
      id: "123e4567-e89b-12d3-a456-426614174001",
      imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fkeanu.jpg?alt=media&token=6056520c-ef3e-4823-aad0-108aab163115",
      name: "Keanu Reeves"
    }
  ])
}

编写用于重置种子数据的 mutation

在进行原型设计和执行 CI/CD 时,将数据重置为零状态以针对新数据集执行一系列新测试可能很有用。

为此,如果您的原型代码未向表格添加记录,请使用 Data Connect 提供的 _upsertMany 突变。

在以下示例中,movie_upsertMany 会使用初始值进行调用,以将电影记录更新为原始状态。

mutation {
  # Execute an upsertMany operation to update the Movie table
  movie_upsertMany(data: [
    {
      id: "550e8400-e29b-41d4-a716-446655440000",
      title: "Inception",
      imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Finception.jpg?alt=media&token=07b09781-b302-4623-a5c3-1956d0143168",
      genre: "sci-fi",
    },
    {
      id: "550e8400-e29b-41d4-a716-446655440001",
      title: "The Matrix",
      imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Fthe_matrix.jpg?alt=media&token=4975645d-fef8-409e-84a5-bcc1046e2059",
      genre: "action",
    }
   
}

生产开发:使用 Admin SDK 填充和更新

如果您想在特权环境中工作,可以使用 Firebase Admin SDK。如果您想加载数千条记录,这是一个重要的使用情形,因为批量数据操作对生产数据的关键性。

安装 Firebase Admin SDK

即使您主要在本地工作,Firebase 也建议您设置 Admin SDK,以便您可以在特权环境(包括本地环境)中使用 Firebase Data Connect。您需要为 Node.js 设置 Admin SDK

您可以详细了解在其他 Data Connect 使用情形下使用 Admin SDK

批量加载和更新生产数据

批量数据管理 API 会代表您构建 GraphQL mutation,而不是要求您使用前面介绍的 executeGraphQL API 构建 mutation {...} 字符串,以便在本地添加一些行。

管理 API 的一个主要优势在于,能够单独管理和重复使用 CI/CD 流的数据数组,或为生产数据设置大型批量数据文件。

以下代码段演示了如何设置批量数据脚本。

import { initializeApp } from 'firebase-admin/app';
import { getDataConnect } from 'firebase-admin/data-connect';

const app = initializeApp();

const dc = getDataConnect({ location: "us-west2", serviceId: "my-service" });

const data = [
 {
      id: "550e8400-e29b-41d4-a716-446655440000",
      title: "Inception",
      imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Finception.jpg?alt=media&token=07b09781-b302-4623-a5c3-1956d0143168",
      genre: "sci-fi",
  },
  {
      id: "550e8400-e29b-41d4-a716-446655440001",
      title: "The Matrix",
      imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Fthe_matrix.jpg?alt=media&token=4975645d-fef8-409e-84a5-bcc1046e2059",
      genre: "action",
    }
];

// Methods of the bulk operations API
const resp = await dc.insert("movie" /*table name*/, data[0]);
// Or
const resp = await dc.insertMany("movie" /*table name*/, data);

// Or
const resp = await dc.upsert("movie" /*table name*/, data[0]);
// Or
const resp = await dc.upsertMany("movie" /*table name*/, data);

生产环境开发:使用 SQL 批量更新数据

如果您在生产环境中处理稳定的架构,并且不修改架构,则可以在 Cloud SQL 实例中管理数据加载和更新。

请参阅有关导入数据的 Cloud SQL for PostgreSQL 指南

后续步骤