如何编写支持Postgres与Sqlite的Drizzle TypeScript代码
实现Drizzle ORM同时适配PostgreSQL(生产)与SQLite(测试)
完全可以实现这个需求,Drizzle ORM本身支持多数据库适配,你可以通过两种方案达成目标:统一Schema适配多数据库,或是分库编写Schema并动态切换。以下是具体实现方式:
方案一:统一Schema适配多数据库
这种方案只需编写一套核心字段定义,再针对不同数据库用对应的表构造器包装,避免重复代码。
步骤1:编写通用字段定义
创建通用的Schema文件(比如src/schema/core.ts),只定义字段类型和约束,不关联具体数据库:
import { int, varchar, primaryKey, unique, notNull } from "drizzle-orm"; // 通用字段配置,不绑定特定数据库 export const usersFields = { id: int("id").primaryKey({ autoIncrement: true }), username: varchar("username", { length: 255 }).unique().notNull(), };
步骤2:分别创建数据库连接与表实例
针对PostgreSQL和SQLite各自创建连接文件,用对应数据库的table构造器包装通用字段:
PostgreSQL连接(src/db/postgres.ts)
import { drizzle } from "drizzle-orm/node-postgres"; import { Client } from "pg"; import { pgTable } from "drizzle-orm/pg-core"; import { usersFields } from "../schema/core"; const client = new Client({ connectionString: process.env.DATABASE_URL }); await client.connect(); export const db = drizzle(client, { schema: { users: pgTable("users", usersFields), }, });
SQLite连接(src/db/sqlite.ts)
import { drizzle } from "drizzle-orm/better-sqlite3"; import Database from "better-sqlite3"; import { sqliteTable } from "drizzle-orm/sqlite-core"; import { usersFields } from "../schema/core"; const sqlite = new Database("test.db"); export const db = drizzle(sqlite, { schema: { users: sqliteTable("users", usersFields), }, });
步骤3:通过环境变量动态切换
创建入口文件(src/db/index.ts),根据环境变量选择使用的数据库实例:
import { db as postgresDb } from "./postgres"; import { db as sqliteDb } from "./sqlite"; // 根据NODE_ENV自动切换:测试环境用SQLite,生产用PostgreSQL export const db = process.env.NODE_ENV === "test" ? sqliteDb : postgresDb;
方案二:分库编写Schema并动态切换
如果两种数据库的Schema差异较大(比如字段类型、约束逻辑不同),可以编写两套独立的Schema,再通过环境变量切换使用。
步骤1:编写分库Schema
分别创建PostgreSQL和SQLite专属的Schema文件:
PostgreSQL Schema(src/schema/postgres.ts)
import { pgTable, serial, varchar, unique, notNull } from "drizzle-orm/pg-core"; export const users = pgTable("users", { id: serial("id").primaryKey(), // PostgreSQL用serial实现自增 username: varchar("username", { length: 255 }).unique().notNull(), });
SQLite Schema(src/schema/sqlite.ts)
import { sqliteTable, integer, text, unique, notNull } from "drizzle-orm/sqlite-core"; export const users = sqliteTable("users", { id: integer("id").primaryKey({ autoIncrement: true }), // SQLite用integer+autoIncrement username: text("username").unique().notNull(), });
步骤2:动态导入并切换数据库
在数据库入口文件中,根据环境变量动态导入对应Schema和数据库连接:
let db; if (process.env.NODE_ENV === "test") { // 测试环境:导入SQLite依赖与Schema const { drizzle } = await import("drizzle-orm/better-sqlite3"); const Database = await import("better-sqlite3"); const { users } = await import("../schema/sqlite"); const sqlite = new Database("test.db"); db = drizzle(sqlite, { schema: { users } }); } else { // 生产环境:导入PostgreSQL依赖与Schema const { drizzle } = await import("drizzle-orm/node-postgres"); const { Client } = await import("pg"); const { users } = await import("../schema/postgres"); const client = new Client({ connectionString: process.env.DATABASE_URL }); await client.connect(); db = drizzle(client, { schema: { users } }); } export { db };
注意事项
- 处理数据库差异:两种数据库的部分特性存在差异,比如自增字段类型、字符串类型(PostgreSQL的
varcharvs SQLite的text)、高级约束等,需要在Schema中针对性处理。 - 迁移脚本:使用Drizzle Kit时,可以创建两份配置文件(比如
drizzle.config.pg.ts和drizzle.config.sqlite.ts),分别生成对应数据库的迁移脚本:# 生成PostgreSQL迁移 drizzle-kit generate:pg --config drizzle.config.pg.ts # 生成SQLite迁移 drizzle-kit generate:sqlite --config drizzle.config.sqlite.ts
内容的提问来源于stack exchange,提问作者Michael Lorton
相关产品推荐
相关产品推荐

