ข้ามไปเนื้อหาหลัก

Category: guide

Drizzle ORM — Type-safe SQL ที่ไม่ซ่อน SQL จากคุณ

คู่มือ Drizzle ORM สำหรับ TypeScript — schema definition, query builder, migration และใช้กับ SQLite, PostgreSQL

· อ่านประมาณ 2 นาที

สารบัญ

Drizzle คืออะไร

Drizzle เป็น TypeScript ORM ที่เน้น type safety และ SQL-like API — ต่างจาก Prisma ตรงที่ query จะ “อ่านเหมือน SQL” ไม่ซ่อน complexity ไว้ข้างหลัง

ติดตั้ง (SQLite)

npm install drizzle-orm better-sqlite3
npm install -D drizzle-kit @types/better-sqlite3

กำหนด Schema

// src/db/schema.ts
import { sqliteTable, integer, text, real } from 'drizzle-orm/sqlite-core';
import { sql } from 'drizzle-orm';

export const products = sqliteTable('products', {
  id:          integer('id').primaryKey({ autoIncrement: true }),
  name:        text('name').notNull(),
  price:       real('price').notNull(),
  category:    text('category').notNull(),
  createdAt:   text('created_at').default(sql`(datetime('now'))`),
  isActive:    integer('is_active', { mode: 'boolean' }).default(true),
});

export type Product    = typeof products.$inferSelect;
export type NewProduct = typeof products.$inferInsert;

เชื่อมต่อ

// src/db/index.ts
import Database from 'better-sqlite3';
import { drizzle } from 'drizzle-orm/better-sqlite3';
import * as schema from './schema';

const sqlite = new Database('local.db');
export const db = drizzle(sqlite, { schema });

CRUD Operations

import { db } from './db';
import { products } from './db/schema';
import { eq, like, and, gte, desc } from 'drizzle-orm';

// Insert
const [newProduct] = await db.insert(products).values({
  name: 'Akrapovic Exhaust', price: 45000, category: 'exhaust',
}).returning();

// Select — typed ครบ
const all = await db.select().from(products);
const byId = await db.select().from(products).where(eq(products.id, 1));

// Filter + sort
const expensive = await db
  .select()
  .from(products)
  .where(and(gte(products.price, 10000), eq(products.isActive, true)))
  .orderBy(desc(products.price))
  .limit(10);

// Update
await db.update(products)
  .set({ price: 48000 })
  .where(eq(products.id, 1));

// Delete
await db.delete(products).where(eq(products.id, 1));

Migrations

# สร้าง migration จาก schema
npx drizzle-kit generate

# Apply migration
npx drizzle-kit migrate

# Drizzle Studio — GUI browser
npx drizzle-kit studio
// drizzle.config.ts
import { defineConfig } from 'drizzle-kit';

export default defineConfig({
  schema:  './src/db/schema.ts',
  out:     './drizzle',
  dialect: 'sqlite',
  dbCredentials: { url: './local.db' },
});

กับ Turso (LibSQL)

import { drizzle } from 'drizzle-orm/libsql';
import { createClient } from '@libsql/client';

const client = createClient({
  url:       process.env.TURSO_URL!,
  authToken: process.env.TURSO_TOKEN!,
});
export const db = drizzle(client, { schema });

เมื่อไหร่เลือก Drizzle: อยากควบคุม SQL query ได้ชัดเจน, ต้องการ performance สูง, หรือทีมถนัด SQL — ถ้าอยากให้ ORM abstract SQL ออกไปให้มาก ใช้ Prisma แทน