Gerenciar migrações do banco de dados do core

Nesta página

As migrações do core do EmDash atualizam as tabelas próprias do EmDash e as colunas padrão nas tabelas de conteúdo. Elas não criam, removem ou renomeiam suas coleções e campos; consulte Evolving a Deployed Site para alterações no modelo de conteúdo.

O modo de migração em tempo de execução é auto por padrão, então deploys existentes continuam aplicando migrações do core pendentes na inicialização. Migrações gerenciadas pelo deploy permitem que um build migre seu banco de dados antes que o novo código da aplicação receba tráfego, e então permitem que o runtime verifique ou confie nessa etapa de deploy.

Build, migrate, deploy, check

Um build ou sync do Astro escreve .emdash/migrations.json. Este manifesto sem segredos registra a versão exata do EmDash, o conjunto ordenado de migrações, a configuração de locale e o executor de migrações do adaptador usado por esse build.

Execute estes comandos do projeto cujas dependências produziram o manifesto. Primeiro faça o build e inspecione o alvo.

pnpm build
pnpm emdash migrate --status

Após confirmar que o alvo reportado é o banco de dados pretendido, inicie a migração interativa. Revise o alvo novamente no prompt antes de confirmar. Então faça o deploy do mesmo build e verifique o schema implantado.

pnpm emdash migrate
pnpm wrangler deploy
pnpm emdash migrate --check

emdash migrate --status reporta migrações aplicadas, pendentes e desconhecidas sem alterar o banco de dados. O comando simples emdash migrate exibe o alvo e solicita confirmação antes de aplicar migrações pendentes.

--check nunca aplica migrações e termina com código diferente de zero quando há migrações conhecidas pendentes ou o banco de dados contém registros de migração desconhecidos para o build. Use --status quando quiser inspecionar os mesmos conjuntos de migrações sem o status de saída diferente de zero “trabalho necessário” do check. A referência CLI distingue códigos de saída pendentes, desconhecidos, de confirmação, interrupção e operacionais.

A aplicação não interativa e toda aplicação com --json requerem --expected-target-fingerprint; o comando falha se o alvo resolvido não corresponder. Use essas opções em jobs de deploy automatizados, não para o fluxo de trabalho interativo descrito acima.

Use --manifest path/to/migrations.json para um manifesto armazenado em outro lugar. Para investigação local, --from-config [--config astro.config.mjs] avalia explicitamente a configuração de projeto confiável sem executar hooks do Astro ou iniciar um servidor. Pipelines de deploy devem consumir o manifesto do build.

Selecionar o banco de dados explicitamente

O adaptador configurado contribui informações de alvo sem segredos para o manifesto. As credenciais permanecem em variáveis de ambiente e são lidas apenas pelo comando de migração.

AdaptadorAlvo do manifestoVariável de credencial padrãoOverride útil
SQLiteCaminho do banco de dados ou URL file:--database <caminho>
libSQLURL públicaTURSO_AUTH_TOKENConfigurar migrationAuthTokenEnv
PostgreSQLNome da variável de conexãoDATABASE_URL--database-url-env <nome>
Cloudflare D1Nome do binding WranglerCLOUDFLARE_API_TOKEN--d1, --account-id, --wrangler-config, --wrangler-env
HyperdriveNome do binding primário e variável de origemVariável direct-origin específica do bindingConfigurar migrationConnectionStringEnv

Caminhos SQLite relativos são resolvidos a partir da raiz do projeto, não do pacote EmDash instalado ou do subdiretório atual do shell. Rótulos de alvo PostgreSQL, libSQL e Hyperdrive omitem credenciais e parâmetros de URL.

Provisionar D1 antes de migrá-lo

Criar um banco de dados D1 e migrar seu schema são operações separadas. emdash migrate nunca cria um banco de dados ausente.

  1. Provisione o banco de dados e registre seu UUID de produção.

    pnpm wrangler d1 create my-site-production
  2. Adicione esse UUID ao binding e ambiente pretendidos em wrangler.jsonc.

  3. Faça o build do site para que o binding D1 seja registrado em .emdash/migrations.json.

  4. Defina o ID da conta e um token com permissão de edição D1. Inspecione o alvo selecionado, então execute a migração interativa. Confirme o prompt apenas quando a conta e o banco de dados corresponderem ao banco de dados de produção pretendido.

    export CLOUDFLARE_ACCOUNT_ID="..."
    export CLOUDFLARE_API_TOKEN="..."
    pnpm emdash migrate \
      --status \
      --wrangler-config wrangler.jsonc \
      --wrangler-env production
    pnpm emdash migrate \
      --wrangler-config wrangler.jsonc \
      --wrangler-env production

Alternativamente, você pode fornecer --account-id com --d1 <uuid-ou-nome-do-banco>. A busca por nome deve resolver exatamente um banco de dados. IDs de preview, IDs de placeholder, contas conflitantes e bindings ambíguos falham de forma fechada.

Configurar migrações D1 no CI

D1 não fornece o bloqueio de migração consultivo usado pelo PostgreSQL. Execute no máximo um job de migração por conta e UUID de banco de dados.

Defina os seguintes segredos e variáveis no ambiente de CI:

  • Segredo CLOUDFLARE_API_TOKEN: um token com permissão de edição D1.
  • Variável CLOUDFLARE_ACCOUNT_ID: o ID da conta Cloudflare proprietária do banco de dados.
  • Variável D1_DATABASE_ID: o UUID do banco de dados D1 de produção.
  • Variável EMDASH_TARGET_FINGERPRINT: o fingerprint impresso por emdash migrate --status após você ter revisado a conta e o banco de dados localmente.

O seguinte workflow do GitHub Actions usa esses valores e vincula o grupo de concorrência a ambos os identificadores imutáveis do D1. Sua etapa de aplicação é não interativa, então fornece explicitamente o fingerprint do alvo revisado.

name: Deploy

on:
  workflow_dispatch:

concurrency:
  group: emdash-migrations-${{ vars.CLOUDFLARE_ACCOUNT_ID }}-${{ vars.D1_DATABASE_ID }}
  cancel-in-progress: false

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - run: pnpm build
      - name: Inspect EmDash migration target
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
        run: |
          pnpm emdash migrate --status --json \
            --account-id "${{ vars.CLOUDFLARE_ACCOUNT_ID }}" \
            --d1 "${{ vars.D1_DATABASE_ID }}"
      - name: Apply EmDash migrations
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          EMDASH_TARGET_FINGERPRINT: ${{ vars.EMDASH_TARGET_FINGERPRINT }}
        run: |
          pnpm emdash migrate \
            --account-id "${{ vars.CLOUDFLARE_ACCOUNT_ID }}" \
            --d1 "${{ vars.D1_DATABASE_ID }}" \
            --expected-target-fingerprint "$EMDASH_TARGET_FINGERPRINT"
      - run: pnpm wrangler deploy
      - name: Check EmDash migrations
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
        run: |
          pnpm emdash migrate --check \
            --account-id "${{ vars.CLOUDFLARE_ACCOUNT_ID }}" \
            --d1 "${{ vars.D1_DATABASE_ID }}"

Atualize EMDASH_TARGET_FINGERPRINT apenas após revisar um alvo alterado localmente. O fingerprint não contém credenciais, mas alterá-lo sem verificar a conta e o banco de dados remove a proteção contra migrar o banco de dados errado.

Hyperdrive conecta à origem

O executor de migrações do Hyperdrive abre uma conexão PostgreSQL direta à origem. Ele não envia tráfego de migração através do Hyperdrive, não usa o binding em cache opcional e não herda a acessibilidade de rede privada do Worker.

O runner de deploy deve conseguir alcançar a origem. Defina migrationConnectionStringEnv em hyperdrive() quando a variável padrão específica do binding for inadequada, e forneça essa variável apenas para o job de migração. Mantenha separadas as credenciais de runtime do Hyperdrive e as credenciais de deploy direct-origin.

Adotar aplicação em tempo de execução gradualmente

A seguinte configuração de integração EmDash habilita a aplicação em tempo de execução enquanto mantém migrações automáticas em desenvolvimento.

emdash({
	database,
	migrations: {
		runtime: "check",
		dev: "auto",
	},
});
  • auto é o padrão retrocompatível. O runtime na inicialização verifica e aplica migrações pendentes.
  • check realiza uma consulta de status direcional e retorna 503 antes de servir uma requisição quando há migrações conhecidas pendentes. Tolera registros de um build compatível mais recente durante um deploy progressivo.
  • manual não realiza migração ou consulta de status em tempo de execução. Use apenas após o pipeline de deploy aplicar e verificar cada build de forma confiável.

EMDASH_MIGRATIONS_MODE pode sobrescrever o modo em tempo de execução quando o mesmo artefato é promovido através de múltiplos ambientes. Rotas de bypass de configuração e desenvolvimento obedecem ao modo efetivo; não podem migrar silenciosamente atrás de check ou manual.

Um rollout conservador é auto durante a introdução do job de deploy, depois check após o job ser confiável, depois manual quando uma verificação externa é aplicada para cada deploy.

Compatibilidade durante deploys progressivos

As migrações do core seguem o sequenciamento expand/deploy/contract. Um deploy pode temporariamente executar isolados de aplicação antigos e novos contra o banco de dados expandido, e um backfill pode ainda estar em andamento. Não contraia um schema até que cada versão implantada tenha parado de usá-lo.

Registros de migração aplicados desconhecidos são tolerados pelo check em tempo de execução apenas para essa direção de deploy progressivo. A verificação exata da CLI os reporta e apply recusa a mutação, porque o banco de dados pode ser mais recente ou ter um histórico de migração divergente.

Solução de problemas

  • Nenhum manifesto de migração encontrado. Faça o build ou sincronize o projeto primeiro. Use --manifest para uma localização de artefato não padrão ou escolha explicitamente --from-config para investigação local.
  • O artefato não corresponde ao EmDash do projeto. Reconstrua e implante a aplicação e o manifesto juntos. Execute a CLI do projeto em vez de uma instalação global.
  • O alvo está ausente ou é ambíguo. Provisione-o primeiro, então forneça um caminho de banco de dados explícito, nome de variável de conexão, seletor D1 ou configuração e ambiente Wrangler selecionados. O EmDash não adivinha a partir de variáveis de ambiente ou bindings não relacionados.
  • O fingerprint do alvo mudou. Pare e revise a conta, o ambiente, o nome do banco de dados, UUID ou caminho exibidos. Atualize o fingerprint esperado apenas após confirmar o alvo pretendido.
  • Registros de migração desconhecidos estão presentes. Não exclua os registros nem execute apply novamente. Confirme que o artefato da aplicação é a versão pretendida e investigue se um build mais recente ou divergente migrou o banco de dados.
  • Um resultado de escrita D1 é ambíguo. Não repita o comando de migração. Execute emdash migrate --status contra a mesma conta e UUID de banco de dados, inspecione o resultado e escale se a migração parou no meio do caminho.
  • Hyperdrive não consegue conectar. Teste a acessibilidade do runner de deploy à origem PostgreSQL e verifique a variável direct-origin. A conectividade Worker-para-Hyperdrive não prova que o runner pode alcançar a origem.