Kern-Datenbankmigrationen verwalten

Auf dieser Seite

EmDash-Kernmigrationen aktualisieren EmDashs eigene Tabellen und die Standardspalten in Content-Tabellen. Sie erstellen, entfernen oder benennen Ihre Collections und Felder nicht um; siehe Evolving a Deployed Site für Content-Modell-Änderungen.

Der Laufzeit-Migrationsmodus ist standardmäßig auto, sodass bestehende Deployments ausstehende Kernmigrationen beim Start weiterhin anwenden. Deployment-verwaltete Migrationen lassen einen Build seine Datenbank migrieren, bevor neuer Anwendungscode Traffic empfängt, und lassen dann die Laufzeit diesen Deployment-Schritt verifizieren oder ihm vertrauen.

Build, Migrate, Deploy, Check

Ein Astro-Build oder -Sync schreibt .emdash/migrations.json. Dieses geheimnisfreie Manifest zeichnet die exakte EmDash-Version, den geordneten Migrationssatz, die Locale-Konfiguration und den Adapter-Migrations-Executor auf, die von diesem Build verwendet werden.

Führen Sie diese Befehle aus dem Projekt aus, dessen Abhängigkeiten das Manifest erstellt haben. Bauen Sie zuerst und prüfen Sie das Ziel.

pnpm build
pnpm emdash migrate --status

Nachdem Sie bestätigt haben, dass das angezeigte Ziel die beabsichtigte Datenbank ist, starten Sie die interaktive Migration. Überprüfen Sie das Ziel am Prompt erneut, bevor Sie bestätigen. Deployen Sie dann denselben Build und überprüfen Sie das deployte Schema.

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

emdash migrate --status meldet angewandte, ausstehende und unbekannte Migrationen, ohne die Datenbank zu ändern. Der einfache emdash migrate-Befehl zeigt das Ziel an und fragt vor dem Anwenden ausstehender Migrationen nach Bestätigung.

--check wendet niemals Migrationen an und beendet sich mit einem Nicht-Null-Exit-Code, wenn bekannte Migrationen ausstehen oder die Datenbank Migrationseinträge enthält, die dem Build unbekannt sind. Verwenden Sie --status, wenn Sie dieselben Migrationssätze inspizieren möchten, ohne den Nicht-Null-Exit-Status „Arbeit erforderlich” von check. Die CLI-Referenz unterscheidet ausstehende, unbekannte, Bestätigungs-, Unterbrechungs- und operationale Exit-Codes.

Nicht-interaktives Anwenden und jedes --json-Anwenden erfordern --expected-target-fingerprint; der Befehl schlägt fehl, wenn das aufgelöste Ziel nicht übereinstimmt. Verwenden Sie diese Optionen in automatisierten Deployment-Jobs, nicht für den oben beschriebenen interaktiven Workflow.

Verwenden Sie --manifest path/to/migrations.json für ein anderswo gespeichertes Manifest. Für lokale Untersuchungen wertet --from-config [--config astro.config.mjs] die vertrauenswürdige Projektkonfiguration explizit aus, ohne Astro-Hooks auszuführen oder einen Server zu starten. Deployment-Pipelines sollten das Build-Manifest verwenden.

Datenbank explizit auswählen

Der konfigurierte Adapter steuert geheimnisfreie Zielinformationen zum Manifest bei. Anmeldedaten verbleiben in Umgebungsvariablen und werden nur vom Migrationsbefehl gelesen.

AdapterManifest-ZielStandard-Anmeldedaten-VariableNützliche Überschreibung
SQLiteDatenbankpfad oder file:-URL--database <Pfad>
libSQLÖffentliche URLTURSO_AUTH_TOKENmigrationAuthTokenEnv konfigurieren
PostgreSQLName der VerbindungsvariableDATABASE_URL--database-url-env <Name>
Cloudflare D1Wrangler-Binding-NameCLOUDFLARE_API_TOKEN--d1, --account-id, --wrangler-config, --wrangler-env
HyperdrivePrimärer Binding- und Origin-VariablennameBinding-spezifische Direct-Origin-VariablemigrationConnectionStringEnv konfigurieren

Relative SQLite-Pfade werden vom Projektstammverzeichnis aufgelöst, nicht vom installierten EmDash-Paket oder dem aktuellen Unterverzeichnis der Shell. PostgreSQL-, libSQL- und Hyperdrive-Zielbezeichnungen lassen Anmeldedaten und URL-Parameter aus.

D1 vor der Migration bereitstellen

Das Erstellen einer D1-Datenbank und das Migrieren ihres Schemas sind separate Vorgänge. emdash migrate erstellt niemals eine fehlende Datenbank.

  1. Stellen Sie die Datenbank bereit und notieren Sie deren Produktions-UUID.

    pnpm wrangler d1 create my-site-production
  2. Fügen Sie diese UUID zum beabsichtigten Binding und Environment in wrangler.jsonc hinzu.

  3. Bauen Sie die Website, damit das D1-Binding in .emdash/migrations.json aufgezeichnet wird.

  4. Setzen Sie die Account-ID und ein Token mit D1-Edit-Berechtigung. Prüfen Sie das ausgewählte Ziel, dann führen Sie die interaktive Migration aus. Bestätigen Sie den Prompt nur, wenn Account und Datenbank mit der beabsichtigten Produktionsdatenbank übereinstimmen.

    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

Sie können stattdessen --account-id mit --d1 <Datenbank-UUID-oder-Name> angeben. Die Namenssuche muss genau eine Datenbank ergeben. Preview-IDs, Platzhalter-IDs, widersprüchliche Accounts und mehrdeutige Bindings schlagen geschlossen fehl.

D1-Migrationen in CI konfigurieren

D1 bietet nicht die beratende Migrationssperre, die PostgreSQL verwendet. Führen Sie höchstens einen Migrationsjob pro Account und Datenbank-UUID aus.

Setzen Sie die folgenden Geheimnisse und Variablen in der CI-Umgebung:

  • Geheimnis CLOUDFLARE_API_TOKEN: ein Token mit D1-Edit-Berechtigung.
  • Variable CLOUDFLARE_ACCOUNT_ID: die Cloudflare-Account-ID, die die Datenbank besitzt.
  • Variable D1_DATABASE_ID: die Produktions-D1-Datenbank-UUID.
  • Variable EMDASH_TARGET_FINGERPRINT: der Fingerprint, den emdash migrate --status ausgibt, nachdem Sie Account und Datenbank lokal überprüft haben.

Der folgende GitHub-Actions-Workflow verwendet diese Werte und beschränkt die Nebenläufigkeitsgruppe auf beide unveränderlichen D1-Identifikatoren. Sein Apply-Schritt ist nicht-interaktiv, daher gibt er den überprüften Ziel-Fingerprint explizit an.

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

Aktualisieren Sie EMDASH_TARGET_FINGERPRINT nur, nachdem Sie ein geändertes Ziel lokal überprüft haben. Der Fingerprint enthält keine Anmeldedaten, aber ihn ohne Überprüfung von Account und Datenbank zu ändern, entfernt den Schutz vor der Migration der falschen Datenbank.

Hyperdrive verbindet sich mit dem Origin

Hyperdrives Migrations-Executor öffnet eine direkte PostgreSQL-Verbindung zum Origin. Er sendet keinen Migrationsverkehr durch Hyperdrive, verwendet nicht das optionale gecachte Binding und erbt keine Private-Network-Erreichbarkeit vom Worker.

Der Deployment-Runner muss den Origin erreichen können. Setzen Sie migrationConnectionStringEnv auf hyperdrive(), wenn die standardmäßige binding-spezifische Variable ungeeignet ist, und stellen Sie diese Variable nur dem Migrationsjob zur Verfügung. Halten Sie Laufzeit-Hyperdrive-Anmeldedaten und Direct-Origin-Deployment-Anmeldedaten getrennt.

Laufzeiterzwingung schrittweise einführen

Die folgende EmDash-Integrationskonfiguration aktiviert die Laufzeiterzwingung und behält automatische Migrationen in der Entwicklung bei.

emdash({
	database,
	migrations: {
		runtime: "check",
		dev: "auto",
	},
});
  • auto ist der abwärtskompatible Standard. Die Laufzeit prüft und wendet beim Start ausstehende Migrationen an.
  • check führt eine gerichtete Statusabfrage durch und gibt 503 zurück, bevor eine Anfrage bedient wird, wenn bekannte Migrationen ausstehen. Es toleriert Einträge aus einem neueren kompatiblen Build während eines Rolling Deployments.
  • manual führt keine Laufzeitmigration oder Statusabfrage durch. Verwenden Sie es nur, nachdem die Deployment-Pipeline jeden Build zuverlässig anwendet und prüft.

EMDASH_MIGRATIONS_MODE kann den Laufzeitmodus überschreiben, wenn dasselbe Artefakt durch mehrere Umgebungen befördert wird. Setup- und Entwicklungs-Bypass-Routen befolgen den effektiven Modus; sie können nicht stillschweigend hinter check oder manual migrieren.

Eine konservative Einführung ist auto während der Einführung des Deployment-Jobs, dann check nachdem der Job zuverlässig ist, dann manual wenn eine externe Prüfung für jedes Deployment durchgesetzt wird.

Kompatibilität während Rolling Deploys

Kernmigrationen folgen dem Expand/Deploy/Contract-Sequencing. Ein Deployment kann vorübergehend alte und neue Anwendungsisolate gegen die erweiterte Datenbank ausführen, und ein Backfill kann noch in Bearbeitung sein. Kontrahieren Sie ein Schema nicht, bis jede deployte Version aufgehört hat, es zu verwenden.

Unbekannte angewandte Migrationseinträge werden von der Laufzeit-check nur für diese Rolling-Deployment-Richtung toleriert. Die exakte Prüfung der CLI meldet sie und apply verweigert die Mutation, weil die Datenbank neuer sein könnte oder eine divergente Migrationshistorie haben könnte.

Fehlerbehebung

  • Kein Migrationsmanifest gefunden. Bauen oder synchronisieren Sie das Projekt zuerst. Verwenden Sie --manifest für einen nicht-standardmäßigen Artefaktort oder wählen Sie explizit --from-config für lokale Untersuchungen.
  • Das Artefakt stimmt nicht mit dem Projekt-EmDash überein. Bauen und deployen Sie Anwendung und Manifest zusammen. Führen Sie die CLI des Projekts statt einer globalen Installation aus.
  • Das Ziel fehlt oder ist mehrdeutig. Stellen Sie es zuerst bereit, dann geben Sie einen expliziten Datenbankpfad, Verbindungsvariablennamen, D1-Selektor oder ausgewählte Wrangler-Konfiguration und -Umgebung an. EmDash rät nicht anhand nicht verwandter Umgebungsvariablen oder Bindings.
  • Der Ziel-Fingerprint hat sich geändert. Stoppen Sie und überprüfen Sie den angezeigten Account, die Umgebung, den Datenbanknamen, die UUID oder den Pfad. Aktualisieren Sie den erwarteten Fingerprint nur, nachdem Sie das beabsichtigte Ziel bestätigt haben.
  • Unbekannte Migrationseinträge sind vorhanden. Löschen Sie die Einträge nicht und führen Sie apply nicht erneut aus. Bestätigen Sie, dass das Anwendungsartefakt die beabsichtigte Version ist, und untersuchen Sie, ob ein neuerer oder divergenter Build die Datenbank migriert hat.
  • Ein D1-Schreibergebnis ist mehrdeutig. Wiederholen Sie den Migrationsbefehl nicht. Führen Sie emdash migrate --status gegen denselben Account und dieselbe Datenbank-UUID aus, prüfen Sie das Ergebnis und eskalieren Sie, wenn die Migration mittendrin abgebrochen wurde.
  • Hyperdrive kann keine Verbindung herstellen. Testen Sie die Erreichbarkeit vom Deployment-Runner zum PostgreSQL-Origin und überprüfen Sie die Direct-Origin-Variable. Worker-zu-Hyperdrive-Konnektivität beweist nicht, dass der Runner den Origin erreichen kann.