Database
Source:
src/Cloudflare/D1/Database.ts
A Cloudflare D1 serverless SQL database built on SQLite.
D1 is a serverless relational database that runs at the edge. Create a database as a resource, then bind it to a Worker to run SQL queries.
Creating a Database
Section titled “Creating a Database”Basic database
const db = yield* Cloudflare.D1.Database("my-db");Database with location hint
The primary copy of the data is stored in the chosen region; reads can be served closer to users when read replication is enabled.
const db = yield* Cloudflare.D1.Database("my-db", { primaryLocationHint: "wnam",});Database with read replication
Read replication is the only mutable property after creation — toggling it triggers an update rather than a replacement.
const db = yield* Cloudflare.D1.Database("my-db", { readReplication: { mode: "auto" },});Database in a specific jurisdiction
const db = yield* Cloudflare.D1.Database("my-db", { jurisdiction: "eu",});Migrations
Section titled “Migrations”Point migrations at a folder of migration files. Already-applied
migrations are skipped on subsequent deploys; new files are detected
automatically and applied as part of the next update.
Bookkeeping always lives in Alchemy’s __alchemy_migrations table —
one format, owned by Alchemy. A database previously migrated with
drizzle-kit, Prisma, or wrangler is adopted by a one-way conversion on
first deploy: the old tool’s applied history is copied into Alchemy’s
table and the old table is left frozen (never written, never dropped).
No baselining required. Legacy Alchemy tracking tables are detected by
column shape and upgraded in place.
Apply migrations from a directory
const db = yield* Cloudflare.D1.Database("my-db", { migrations: "./migrations",});Drizzle migrations (adopts an existing drizzle-kit-migrated database)
const schema = yield* Drizzle.Schema("app-schema", { schema: "./src/schema.ts", dialect: "sqlite",});const db = yield* Cloudflare.D1.Database("my-db", { migrations: schema,});Custom bookkeeping table name
const db = yield* Cloudflare.D1.Database("my-db", { migrations: { dir: "./migrations", table: "my_migrations" },});Importing SQL
Section titled “Importing SQL”Use importFiles to seed the database with raw .sql files via Cloudflare’s
D1 import API. Each file is hashed; only files whose contents change are
re-imported on subsequent deploys.
const db = yield* Cloudflare.D1.Database("my-db", { importFiles: ["./seed/users.sql", "./seed/posts.sql"],});Cloning a Database
Section titled “Cloning a Database”clone performs a full export → import from a source database during
creation. It accepts a D1Database resource, a { databaseId }, or a
{ name } to look up by name.
Clone by passing the source resource directly
const source = yield* Cloudflare.D1.Database("source-db");const cloned = yield* Cloudflare.D1.Database("cloned-db", { clone: source,});Clone by databaseId
const cloned = yield* Cloudflare.D1.Database("cloned-db", { clone: { databaseId: "abcdef12-3456-7890-abcd-ef1234567890" },});Clone by name
const cloned = yield* Cloudflare.D1.Database("cloned-db", { clone: { name: "source-db" },});Binding to a Worker
Section titled “Binding to a Worker”const db = yield* Cloudflare.D1.QueryDatabase(MyDatabase);
// Run a queryconst results = yield* db.prepare("SELECT * FROM users WHERE id = ?") .bind(userId) .all();
// Execute a mutationyield* db.prepare("INSERT INTO users (id, name) VALUES (?, ?)") .bind(newId, name) .run();