drizzle-team / drizzle-orm

Headless TypeScript ORM with a head. Runs on Node, Bun and Deno. Lives on the Edge and yes, it's a JavaScript ORM too 😅
https://orm.drizzle.team
Apache License 2.0
24.51k stars 643 forks source link

[FEATURE]: allow multiple adapters on withReplicas #1606

Open unnoq opened 11 months ago

unnoq commented 11 months ago

Describe what you want

Here is my code, and I have tested it. However, it has a TypeScript error. I am unsure if this is not allowed or just a TypeScript error.

If you're wondering why I'm combining postgres and neon, it's because neon doesn't support transactions yet.

import { neon, neonConfig } from '@neondatabase/serverless'
import { drizzle as drizzleNeon } from 'drizzle-orm/neon-http'
import { withReplicas } from 'drizzle-orm/pg-core'
import { drizzle as drizzlePostgres } from 'drizzle-orm/postgres-js'
import postgres from 'postgres'
import * as schema from '../database/schema'
import type { Env } from '../env'

neonConfig.fetchConnectionCache = true

export function createDb({ env }: { env: Env }) {
  const write = drizzlePostgres(postgres(env.DATABASE_URL), {
    schema,
    logger: env.WORKER_ENV === 'development',
  })
  const read = drizzleNeon(neon(env.DATABASE_URL), { schema, logger: env.WORKER_ENV === 'development' })

  // @ts-ignore TODO: fix type for withReplicas
  return withReplicas(write, [read])
}
Angelelz commented 11 months ago

How are you keeping the databases in sync?

unnoq commented 11 months ago

@Angelelz Both connections originate from Neon, which means they interact with the same database.

Angelelz commented 11 months ago

I guess this was not the intended use-case. I guess you can just cast it:

const read = drizzleNeon(neon(env.DATABASE_URL), { schema, logger: env.WORKER_ENV === 'development' }) as typeof write
unnoq commented 11 months ago

@Angelelz Currently, I am doing something similar, but it's not ideal. I'm not sure if it's completely safe.

Angelelz commented 11 months ago

I don't think you'll have a problem, the underlying runtime lives in "drizzle-orm/sqlite-core" and the stuff that's different extends the same sqlite classes. I'm not sure what can be done at the drizzle side for this, other than making the types more relaxed? The other suggestion is to just have 2 different db objects and import the appropriate one depending on what you need to do.