播種資料並執行大量資料作業

在 Firebase SQL Connect 中,您可以根據工作流程和環境,以不同方式執行大量資料載入和更新作業:

  • 在本機原型設計中,嘗試替代結構定義時,您可以使用 SQL Connect VS Code 擴充功能、SQL Connect 模擬器和本機資料庫執行個體,在本機開發環境中建立及呼叫資料播種變異。

  • 在正式環境開發中,如果結構定義穩定,且您正在執行較大的 CI/CD 流程及管理正式環境資料,則有兩種選擇:

    • 建議的做法是使用 Firebase Admin SDK,這是一組在特殊權限環境中執行的程式庫。

    • 您也可以搭配 Cloud SQL 執行個體使用 SQL 工具,執行大量載入和更新作業,只要修改的是「資料」而非「資料庫結構定義」即可。如果直接使用 SQL 工具修改資料庫結構定義,可能會破壞 SQL Connect 結構定義和連接器。

本機原型設計:本機執行個體中的種子資料

在入門指南中,您設定了應用程式,使用臨時插入異動將單一記錄新增至單一資料表。

為了讓電影評論應用程式能正常運作,需要電影、評論和使用者的資料,以便在多個資料表上使用彙整和其他作業,對查詢和變更進行原型設計。您可以擴充結構定義,並為資料庫提供種子資料。

原型設計環境需要程式碼來執行資料植入。本指南提供一些範例,說明:

  • 在個別資料表上使用 _insertMany 和 _upsertMany
  • 在相關資料表上使用 _insertMany

更新電影評論應用程式結構定義

您可以使用 _insertMany 和 _upsertMany 異動,一次更新一個資料庫資料表,或更新多個透過 join 關係連結的資料表。以下是展開的電影評論應用程式結構定義,有助於說明這些用途和範例。它將 schema.gql 擴展到起始 Movie 類型之外,納入 Actor 和 MovieActor 類型,因此我們可以建立更複雜的查詢原型。

# 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"
}

編寫異動來植入零狀態資料

在原型設計期間,如果需要針對一系列離散值測試查詢和變異,您可以使用多筆記錄填入資料。舉例來說,您可能想新增多筆電影記錄,並設定不同的類型和分級,以便測試比較和篩選功能。

將資料填充至 Movie 和 Actor 資料表

視原型設計階段而定,您可以使用「入門指南」中介紹的相同技術插入一或兩筆記錄:也就是說,您可以使用 SQL Connect VS Code 擴充功能中的 CodeLens 建立 _insert 異動、硬式編碼資料,並在 VS Code 中執行這些異動。

最後,使用 _insertMany 作業將多筆記錄新增至資料表會更合理。在電影評論應用程式範例中,這會在 Movie 和 Actor 中插入初始資料集。

如要執行下列異動,請使用 SQL Connect VS Code 擴充功能,在適當的檔案編輯器檢視畫面中,按一下「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"
    }
  ])
}

如要以不可分割的方式植入相關資料表,可以使用常值酬載執行巢狀關聯插入。這樣一來,系統就會在單一作業中建立父項記錄和相關聯的子項記錄,不需要手動建立外鍵關聯。

如為一對多關係,請提供巢狀子記錄陣列。如果是一對一關係,請提供單一巢狀子項物件。

# Nested insert for Movie and Review (one-to-many)
# 1 movie and 2 reviews shown
mutation {
  movie_insert(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",
    reviews_on_movie: [
      {
        id: "123e4567-e89b-12d3-a456-426614174002",
        rating: 5,
        reviewText: "Amazing concept!",
        user: { id: "user-uuid-123" }
      },
      {
        id: "123e4567-e89b-12d3-a456-426614174003",
        rating: 4,
        reviewText: "A bit confusing, but great.",
        user: { id: "user-uuid-456" }
      }
    ]
  })
}
# Nested insert for User and Profile (one-to-one)
mutation {
  user_insert(data: {
    id: "user-uuid-123",
    name: "Alice",
    profile_on_user: {
      bio: "Avid moviegoer and critic."
    }
  })
}

編寫重設種子資料的異動

在原型設計和執行 CI/CD 時,將資料重設為零狀態,以便對新資料集執行一系列新測試,可能會很有幫助。

如果原型程式碼不會在資料表中新增記錄,請使用 SQL 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 SQL Connect。您必須設定 Node.js 的 Admin SDK。

如要進一步瞭解如何在其他 SQL Connect 用途中使用 Admin SDK,請參閱這篇文章。

大量載入及更新正式環境資料

大量資料管理 API 會代您建構 GraphQL 異動,而不是要求您使用前述的 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",
    // Nested reviews can be inserted atomically along with the movie
    reviews_on_movie: [
      {
        rating: 5,
        reviewText: "Amazing concept!",
        user: { id: "user-123" } // Link to existing user
      }
    ]
  },
  {
    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",
    reviews_on_movie: [
      {
        rating: 5,
        reviewText: "A masterpiece of sci-fi action.",
        user: { id: "user-456" }
      }
    ]
  }
];

// 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 指南,瞭解如何匯入資料。

後續步驟