drizzle-team / drizzle-team/drizzle-orm

[FEATURE]: Expose Cloudflare Compatible `generateSQLiteMigration` to use with Durable Objects

Open
#4,301 4 comments 3 reactions 0 assignees View on GitHub
driver/durable-objects enhancement
Dominant language
TypeScript
Stars
35.8k
Forks
1.6k
Avg merge
2d 7h
Merged PRs (30d)
4

Description

### Feature hasn't been suggested before.

- [x] I have verified this feature I'm about to request hasn't been suggested before.

### Describe the enhancement you want to request

It would be interesting to create and manage more complicated SQLite schemas with Cloudflare Durable object by setting everything up with Drizzle

This code will create the SQL statements for the schema.

```ts
import { generateSQLiteDrizzleJson, generateSQLiteMigration } from 'drizzle-kit/api'

export async function generateSqLiteSchema({
prevSchema,
schema,
}: {
prevSchema: Record
schema: Record
}) {
const prevSchemaJson = await generateSQLiteDrizzleJson(prevSchema)
const currentSchemaJson = await generateSQLiteDrizzleJson(schema)
const sql = await generateSQLiteMigration(prevSchemaJson, currentSchemaJson)
return sql.join('\n')
}
```
In theory, one could then generate the migrations with an API like below. I guess another improvement would be to pass the prior schema through in the generate function in the constructor. Anyways...

The problem here is `fs` is bundled with `drizzle-kit/api` so this will error out on Cloudflare.

```ts
import { DurableObject } from 'cloudflare:workers'
import { generateSqLiteSchema } from './generate.ts'
import { Browsable } from '@outerbase/browsable-durable-object'
import type { DrizzleSqliteDODatabase } from 'drizzle-orm/durable-sqlite'
import { drizzle } from 'drizzle-orm/durable-sqlite'
import { sqliteTable, text } from 'drizzle-orm/sqlite-core'

const schema = {
users: sqliteTable('users', {
id: text('id').primaryKey(),
name: text('name'),
}),
}

type Bindings = {
DRIZZLE_DO: DurableObjectNamespace
}

@Browsable()
export class DrizzleDurableObject extends DurableObject {
storage: DurableObjectStorage
db: DrizzleSqliteDODatabase
constructor(ctx: DurableObjectState, env: Bindings) {
super(ctx, env)
this.storage = ctx.storage
this.db = drizzle(this.storage, { logger: true })
ctx.blockConcurrencyWhile(async () => {
// This fails due to fs access
await generateSqLiteSchema({
prevSchema: {},
schema,
})
})
}

override async fetch(request: Request): Promise {
return new Response('Hello from MyDurableObject')
}
}

export default {
async fetch(request: Request, env: Bindings, ctx: ExecutionContext): Promise {
const path = new URL(request.url).pathname
const id: DurableObjectId = env.DRIZZLE_DO.idFromName(path)
const stub = env.DRIZZLE_DO.get(id)

return stub.fetch(request)
},
} satisfies ExportedHandler
```

cc @Brayden

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.