feat: migrate all DO SQLite raw SQL to Drizzle ORM#684
feat: migrate all DO SQLite raw SQL to Drizzle ORM#684
Conversation
Migrate ~140 raw sql.exec() queries across 8 Durable Objects in 7 workers to use drizzle-orm with the durable-sqlite driver. Each worker gets a Drizzle schema (sqlite-schema.ts), generated migrations, and type-safe query builder calls replacing hand-rolled SQL strings. Workers migrated: - cloudflare-o11y (AlertConfigDO) - cloudflare-session-ingest (SessionIngestDO, SessionAccessCacheDO) - cloudflare-ai-attribution (AttributionTrackerDO) - cloudflare-webhook-agent-ingest (TriggerDO) - cloud-agent (events, leases, command-queue) - cloud-agent-next (events, leases) - cloudflare-app-builder (GitRepositoryDO/SqliteFS) Deleted per-worker table.ts interpolator utils, Zod-based table definitions in db/tables/, custom migration systems, and sql-helpers. Added drizzle-kit to the pnpm catalog.
Without this, existing DO instances (which already have tables from the old raw DDL but lack __drizzle_migrations) would fail when Drizzle's migrator tries to run the initial migration.
Code Review SummaryStatus: 2 Issues Remaining | Recommendation: Address before merge Overview
Previous Issues (Resolved ✅)The following issues from earlier review rounds have been confirmed fixed:
Remaining Issues (click to expand)WARNING
Files Reviewed (117 files)Config & Rules:
Documentation:
cloud-agent-next (22 files):
cloud-agent (22 files):
cloudflare-ai-attribution (12 files):
cloudflare-app-builder (10 files):
cloudflare-o11y (6 files):
cloudflare-session-ingest (8 files):
cloudflare-webhook-agent-ingest (10 files):
Generated/Lock files: Overall Assessment: This is a well-executed, large-scale migration (~140 raw SQL queries across 8 DOs in 7 workers) to Drizzle ORM. The migration is consistent across all workers, follows the documented pattern, and previous review feedback has been addressed. The only remaining issues are the two |
…igrate-do-sqlite-to-drizzle # Conflicts: # cloudflare-session-ingest/package.json # pnpm-lock.yaml
…asts, use single-query deletes, fix doc paths
… consistent migrations
Co-authored-by: kilo-code-bot[bot] <240665456+kilo-code-bot[bot]@users.noreply.github.com>
Drizzle's durable-sqlite driver doesn't expose a lazy cursor API, so .all() was loading all matching rows into memory. Replace with batched keyset pagination (500 rows/batch) to bound memory usage while still allowing callers to break early from the generator.
The table query interpolator pattern was removed by the Drizzle ORM migration. Replace with a reference to the Drizzle conventions doc.
Use Drizzle's toSQL() to build type-safe queries, then execute via the raw SqlStorageCursor API. This gives us: - rowsWritten for delete counts (no row materialization) - True lazy cursor iteration in iterateByFilters (no .all()) Each factory function now accepts a rawSql parameter alongside db.
|
Split into base + 8 worker PRs. |
Summary
Migrates ~140 raw
sql.exec()queries across 8 Durable Objects in 7 workers to usedrizzle-ormwith thedurable-sqlitedriver, as specified indocs/migrate-do-sqlite-to-drizzle.md.Net result: -3818 / +3634 lines (net -184)
Workers migrated
cloudflare-o11ycloudflare-session-ingest.onConflictDoUpdate()cloudflare-ai-attribution.innerJoin()+.returning()cloudflare-webhook-agent-ingestcloud-agentand()/inArray()/gt()cloud-agent-nextcloudflare-app-builderPer-worker changes
Each worker gets:
drizzle.config.ts— Drizzle Kit config withdialect: 'sqlite',driver: 'durable-sqlite'src/db/sqlite-schema.ts—sqliteTable()definitions with indexesdrizzle/— Generated migration SQL + journalEach worker loses:
table.tsinterpolator utility (where applicable)src/db/tables/(where applicable)migrations.tsrewritten to use Drizzle migrator)sql-helpers.tsdynamic WHERE clause builders (replaced by Drizzle operators)Backward compatibility
Generated migration SQL uses
CREATE TABLE IF NOT EXISTS/CREATE INDEX IF NOT EXISTSso existing DOs (which already have tables but lack__drizzle_migrations) won't fail when Drizzle runs the initial migration for the first time.Typecheck
pnpm typecheckpasses. All per-worker typechecks show only pre-existing errors inworker-utils/encryption.ts.