drizzle-team / drizzle-team/drizzle-orm
[FEATURE]: Expose Cloudflare Compatible `generateSQLiteMigration` to use with Durable Objects
- 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
Assessment
This issue has not been assessed yet.