No Firebase Data Connect, as operações de dados em massa são realizadas usando mutações. Embora os projetos Data Connect armazenem dados no PostgreSQL, não é possível fazer o carregamento em massa de dados usando instruções ou ferramentas SQL: o serviço Data Connect e os esquemas dele precisam ficar sincronizados com o banco de dados, e operar diretamente no PostgreSQL interromperia essa sincronização.
No Data Connect, você usa mutações para gerar dados e gerenciá-los em massa. É possível criar e chamar mutações de gerenciamento de dados de maneiras diferentes, dependendo dos fluxos de trabalho e dos ambientes:
No desenvolvimento local, quando você está criando protótipos de apps, as mutações de semeadura de dados podem ser criadas e chamadas em um ambiente de desenvolvimento local usando a extensão do VS Code, o emulador Data Connect e uma instância de banco de dados local.
No desenvolvimento de produção, ao executar fluxos de CI/CD maiores e gerenciar dados de produção, é possível usar o Firebase Admin SDK, um conjunto de bibliotecas que são executadas em ambientes privilegiados.
Desenvolvimento local: dados iniciais em instâncias locais
No Guia de início, você configura um app para adicionar um único registro a uma única tabela usando uma mutação de inserção ad hoc.
Para ser utilizável, o app de avaliações de filmes precisa de dados de filmes, avaliações e usuários para consultas e mutações de protótipo que usam mesclagens e outras operações em várias tabelas com dados realistas. Você pode expandir seu esquema e gerar seu banco de dados.
O ambiente de prototipagem precisa de código para realizar a semeadura de dados. Este guia oferece alguns exemplos, ilustrando:
- Uso de
_insertMany
e_upsertMany
em tabelas individuais - Uso de
_insertMany
em tabelas relacionadas
Atualizar o esquema do app de avaliação de filmes
É possível usar as mutações _insertMany
e _upsertMany
para atualizar tabelas de banco de dados individuais uma por vez ou atualizar várias tabelas relacionadas por relacionamentos de mesclagem. Confira abaixo um esquema expandido do app de análise de filmes que ajuda a ilustrar esses
casos de uso e exemplos. Ele expande schema.gql
além do
tipo inicial Movie
para incluir os tipos Actor
e MovieActor
, para que possamos
criar protótipos de consultas mais complexas.
# 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"
}
Gravar mutações para gerar dados de estado zero
Durante a prototipagem, quando suas consultas e mutações precisam ser testadas em um intervalo de valores discretos, é possível preencher dados com vários registros. Por exemplo, você pode adicionar vários registros de filmes com diferentes tipos de gêneros e classificações para testar comparações e filtragem.
Gerar dados nas tabelas Movie
e Actor
Dependendo do seu estágio de prototipagem, você pode usar a mesma técnica
apresentada no guia "Começar" para inserir um ou dois registros: ou seja, você
pode usar CodeLenses na extensão do VS Code para criar mutações _insert
,
codificar dados e executar essas mutações no VS Code.
No final, faz mais sentido adicionar muitos registros a uma tabela usando uma operação _insertMany
. No exemplo do app de análise de filmes, isso insere um
conjunto inicial de dados em Movie
e Actor
.
Para executar as mutações a seguir, usando a extensão do Firebase do VS Code, na visualização do editor de arquivos apropriado, clique nos botões CodeLens Run (Production) ou Run (Local), dependendo se você está criando protótipos com seu serviço de produção ou um banco de dados local.
# 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"
}
])
}
Gerar dados na tabela de mesclagem MovieActor
Para testar consultas e mutações usando junções e outras operações complexas, adicione vários registros à tabela MovieActor
.
Aqui, ao atualizar várias tabelas nesse tipo de relação, é possível
adicionar a diretiva @transaction
para garantir que a atualização seja concluída corretamente.
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"
}
])
}
Escrever uma mutação para redefinir dados de origem
Ao criar protótipos e realizar a CI/CD, redefinir os dados para um estado zero para executar uma nova série de testes em um novo conjunto de dados pode ser útil.
Para fazer isso, se o código do protótipo não adicionar registros às tabelas, use a
mutação _upsertMany
fornecida por Data Connect.
No exemplo abaixo, movie_upsertMany
é chamado com os valores iniciais
para atualizar os registros de filmes para o estado original.
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",
}
…
}
Desenvolvimento de produção: use Admin SDK para preencher e atualizar
O Firebase Admin SDK está disponível para quando você quer trabalhar em ambientes privilegiados. Esse é um caso de uso importante quando você quer carregar milhares de registros, devido à natureza crítica das operações de dados em massa nos dados de produção.
Instalar o Firebase Admin SDK
Mesmo que você trabalhe principalmente localmente, o Firebase recomenda configurar o Admin SDK para que você possa usar Firebase Data Connect em um ambiente privilegiado, incluindo o ambiente local. É necessário configurar o Admin SDK para Node.js.
Saiba mais sobre como usar o SDK Admin em outros casos de uso Data Connect.
Fazer carregamentos e atualizações em massa de dados de produção
A API para gerenciamento de dados em massa cria mutações do GraphQL em seu nome, em vez
de pedir que você crie strings mutation {...}
com a API executeGraphQL
descrita anteriormente para adicionar algumas linhas localmente.
Um dos principais benefícios da API administrativa é a capacidade de gerenciar separadamente e reutilizar matrizes de dados para fluxos de CI/CD ou configurar grandes arquivos de dados em massa para dados de produção.
Os snippets a seguir demonstram como configurar um script de dados em massa.
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);