EmDash unterstützt mehrere Datenbank-Backends. Wählen Sie basierend auf Ihrem Deployment-Ziel.
Übersicht
| Datenbank | Geeignet für | Deployment |
|---|---|---|
| D1 | Cloudflare Workers | Edge, global verteilt |
| Hyperdrive | PostgreSQL auf Cloudflare Workers | Edge, bestehendes Postgres |
| PostgreSQL | Produktion Node.js | Jede Plattform mit Postgres |
| libSQL | Remote-Datenbanken | Edge oder Node.js |
| SQLite | Node.js, lokale Entwicklung | Einzelserver |
Cloudflare D1
D1 ist Cloudflares serverlose SQLite-Datenbank. Verwenden Sie sie bei der Bereitstellung auf Cloudflare Workers.
import { d1 } from "@emdash-cms/cloudflare";
export default defineConfig({
integrations: [
emdash({
database: d1({ binding: "DB" }),
}),
],
});
Konfiguration
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
binding | string | — | D1 Binding-Name aus wrangler.jsonc |
session | string | "disabled" | Lesereplikationsmodus (siehe unten) |
bookmarkCookie | string | "__em_d1_bookmark" | Cookie-Name für Session-Bookmarks |
Einrichtung
wrangler.jsonc
{
"d1_databases": [
{
"binding": "DB",
"database_name": "emdash-db"
}
]
} wrangler.toml
[[d1_databases]]
binding = "DB"
database_name = "emdash-db" Read Replicas
D1 unterstützt Lesereplikation, um die Leselatenz für global verteilte Sites zu senken. Wenn aktiviert, werden Leseabfragen an nahegelegene Replikate statt immer an die primäre Datenbank weitergeleitet.
EmDash verwendet die D1 Sessions API, um dies transparent zu verwalten. Aktivieren Sie es mit der session-Option:
import { d1 } from "@emdash-cms/cloudflare";
export default defineConfig({
integrations: [
emdash({
database: d1({
binding: "DB",
session: "auto",
}),
}),
],
});
Session-Modi
| Modus | Verhalten |
|---|---|
"disabled" | Keine Sessions. Alle Abfragen gehen an die primäre Datenbank. Standard. |
"auto" | Anonyme Anfragen lesen vom nächsten Replikat. Authentifizierte Benutzer erhalten Read-your-writes-Konsistenz über Bookmark-Cookies. |
"primary-first" | Wie "auto", aber die erste Abfrage geht immer an die primäre. Für Sites mit sehr häufigen Schreibvorgängen. |
Funktionsweise
- Anonyme Besucher erhalten
first-unconstrained— Lesezugriffe gehen zum nächsten Replikat für die niedrigste Latenz. Da anonyme Benutzer nie schreiben, benötigen sie keine Konsistenzgarantien. - Authentifizierte Benutzer (Editoren, Autoren) erhalten Bookmark-basierte Sessions. Nach einem Schreibvorgang stellt ein Bookmark-Cookie sicher, dass die nächste Anfrage mindestens diesen Zustand sieht.
- Schreibanfragen (
POST,PUT,DELETE) beginnen immer bei der primären Datenbank. - Build-Zeit-Abfragen (Astro Content Collections) umgehen Sessions vollständig und verwenden direkt die primäre Datenbank.
libSQL
libSQL ist ein Fork von SQLite, der Remote-Verbindungen unterstützt. Verwenden Sie es, wenn Sie eine Remote-Datenbank ohne Cloudflare D1 benötigen.
import { libsql } from "emdash/db";
export default defineConfig({
integrations: [
emdash({
database: libsql({
url: process.env.LIBSQL_DATABASE_URL,
authToken: process.env.LIBSQL_AUTH_TOKEN,
}),
}),
],
});
Konfiguration
| Option | Typ | Beschreibung |
|---|---|---|
url | string | Datenbank-URL (libsql://... oder file:...) |
authToken | string | Auth-Token für Remote-Datenbanken (optional für lokal) |
Lokale Entwicklung
Verwenden Sie eine lokale libSQL-Datei während der Entwicklung:
database: libsql({ url: "file:./data.db" });
PostgreSQL
PostgreSQL wird für Node.js-Deployments unterstützt, die eine vollständige relationale Datenbank benötigen.
import { postgres } from "emdash/db";
export default defineConfig({
integrations: [
emdash({
database: postgres({
connectionString: process.env.DATABASE_URL,
}),
}),
],
});
Konfiguration
Sie können sich mit einem Connection-String oder einzelnen Parametern verbinden:
// Connection-String
database: postgres({
connectionString: "postgres://user:password@localhost:5432/emdash",
});
// Einzelne Parameter
database: postgres({
host: "localhost",
port: 5432,
database: "emdash",
user: "emdash",
password: process.env.DB_PASSWORD,
ssl: true,
});
| Option | Typ | Beschreibung |
|---|---|---|
connectionString | string | PostgreSQL-Verbindungs-URL |
host | string | Datenbank-Host |
port | number | Datenbank-Port |
database | string | Datenbankname |
user | string | Datenbankbenutzer |
password | string | Datenbankpasswort |
ssl | boolean | SSL aktivieren |
pool.min | number | Minimale Pool-Verbindungen (Standard 0) |
pool.max | number | Maximale Pool-Verbindungen (Standard 10) |
Connection Pooling
Der Adapter verwendet intern pg.Pool. Passen Sie die Pool-Größe basierend auf Ihrem Deployment an:
database: postgres({
connectionString: process.env.DATABASE_URL,
pool: { min: 2, max: 20 },
});
Hyperdrive
Verwenden Sie den hyperdrive()-Adapter, um EmDash auf Cloudflare Workers mit einer bestehenden PostgreSQL- — oder Postgres-kompatiblen (z.B. PlanetScale Postgres) — Datenbank zu betreiben. Hyperdrive pooled und beschleunigt die Verbindung über das Cloudflare-Netzwerk; EmDashs PostgreSQL-Dialekt führt die Abfragen aus.
import { hyperdrive, r2 } from "@emdash-cms/cloudflare";
export default defineConfig({
integrations: [
emdash({
database: hyperdrive({ binding: "HYPERDRIVE" }),
storage: r2({ binding: "MEDIA" }),
}),
],
});
Anforderungen
pg >= 8.16.3in Ihrem Projekt installiert (pnpm add pg)compatibility_flags: ["nodejs_compat"]compatibility_date >= "2024-09-23"
Einrichtung
Erstellen Sie die Hyperdrive-Konfiguration und fügen Sie das Binding zu Ihrer Wrangler-Konfiguration hinzu:
wrangler hyperdrive create emdash-db \
--connection-string "postgres://user:password@host/db?sslmode=verify-full" \
--caching-disabled
wrangler.jsonc
{
"hyperdrive": [
{
"binding": "HYPERDRIVE",
"id": "<your-hyperdrive-id>"
}
]
} wrangler.toml
[[hyperdrive]]
binding = "HYPERDRIVE"
id = "<your-hyperdrive-id>" Konfiguration
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
binding | string | "HYPERDRIVE" | Primäres (caching-deaktiviertes) Hyperdrive-Binding |
cachedBinding | string | — | Optionales caching-aktiviertes Binding für anonyme Lesezugriffe |
max | number | 5 | Max. Größe des In-Worker-Connection-Pools zu Hyperdrive |
Anonyme Lesezugriffe aus dem Cache bedienen
Standardmäßig deaktivieren Sie Hyperdrive-Caching vollständig, da Admin und Schreibvorgänge Read-after-Write-Konsistenz benötigen. Aber anonyme öffentliche Lesezugriffe — keine Session, kein Schreibvorgang — können ein kurzes Staleness-Fenster tolerieren. Wenn dieser Kompromiss akzeptabel ist, betreiben Sie zwei Hyperdrive-Konfigurationen über derselben Datenbank: eine mit deaktiviertem Caching (das primäre binding) und eine mit aktiviertem Caching (cachedBinding). EmDash leitet dann anonyme Leseanfragen über das cache-aktivierte Binding, während jede authentifizierte Anfrage und jeder Schreibvorgang auf dem ungecachten primären bleibt, sodass die Read-after-Write-Konsistenz erhalten bleibt.
# Primär — Caching AUS (für Admin, auth. Anfragen, Schreibvorgänge, Migrationen)
wrangler hyperdrive create emdash-db \
--connection-string "postgres://user:password@host/db?sslmode=verify-full" \
--caching-disabled
# Gecacht — GLEICHER Connection-String, Caching AN (nur für anonyme Lesezugriffe)
wrangler hyperdrive create emdash-db-cached \
--connection-string "postgres://user:password@host/db?sslmode=verify-full"
{
"hyperdrive": [
{ "binding": "HYPERDRIVE", "id": "<caching-disabled-id>" },
{ "binding": "HYPERDRIVE_CACHED", "id": "<caching-enabled-id>" }
]
}
database: hyperdrive({ binding: "HYPERDRIVE", cachedBinding: "HYPERDRIVE_CACHED" });
Dies ist das Zwei-Konfigurationen-Muster, das Cloudflare für Caching dokumentiert. EmDash entscheidet pro Anfrage, welches Binding verwendet wird:
- Anonyme Lesezugriffe auf öffentliche Site-Pfade (
GET/HEAD, keine Session, nicht unter/_emdash) → cache-aktiviertescachedBinding. - Authentifizierte Anfragen (Editoren, Autoren) → ungecachtes
binding. - Schreibvorgänge (
POST,PUT,DELETE, einschließlich anonymer) → ungecachtesbinding. - Jede Anfrage unter
/_emdash(Admin, Setup, Auth, interne APIs), auch ein anonymesGET→ ungecachtesbinding. - Migrationen und Kaltstart → immer das primäre
binding.
SQLite
SQLite mit better-sqlite3 ist die einfachste Option für Node.js-Deployments.
import { sqlite } from "emdash/db";
export default defineConfig({
integrations: [
emdash({
database: sqlite({ url: "file:./data.db" }),
}),
],
});
Konfiguration
| Option | Typ | Beschreibung |
|---|---|---|
url | string | Dateipfad mit file:-Präfix |
Dateipfad
Die url muss mit file: beginnen:
// Relativer Pfad
database: sqlite({ url: "file:./data/emdash.db" });
// Absoluter Pfad
database: sqlite({ url: "file:/var/data/emdash.db" });
// Aus Umgebungsvariable
database: sqlite({ url: `file:${process.env.DATABASE_PATH}` });
Migrationen
EmDash führt Migrationen automatisch bei der ersten Anfrage aus, für jeden unterstützten Dialekt (D1, SQLite, libSQL, PostgreSQL). Migrationen sind im emdash-Paket gebündelt und werden in Ihren Build eingebettet.
Wenn die Datenbank leer ist (keine Sammlungen) und der Setup-Assistent nicht abgeschlossen wurde, wendet EmDash beim ersten Start auch eine Seed-Datei an. Der Seed wird aus .emdash/seed.json, dem Pfad in package.json#emdash.seed oder seed/seed.json gelesen — je nachdem, welche zuerst gefunden wird — und zur Kompilierzeit in den Build eingebunden. Wenn keine vorhanden ist, wird ein integriertes Standard-Seed verwendet. Nachfolgende Starts gegen eine bestehende Datenbank lassen deren Inhalt unverändert.
Umgebungsbasierte Konfiguration
Verwenden Sie verschiedene Datenbanken pro Umgebung:
import { sqlite, libsql, postgres } from "emdash/db";
import { d1 } from "@emdash-cms/cloudflare";
const database = import.meta.env.PROD ? d1({ binding: "DB" }) : sqlite({ url: "file:./data.db" });
export default defineConfig({
integrations: [emdash({ database })],
});
Die Wahl kann auch auf einer Umgebungsvariable statt dem Build-Modus basieren:
const database = process.env.DATABASE_URL
? postgres({ connectionString: process.env.DATABASE_URL })
: sqlite({ url: "file:./data.db" });