Bun Drizzle Integration by secondsky/claude-skills
npx skills add https://github.com/secondsky/claude-skills --skill 'Bun Drizzle Integration'Drizzle ORM 结合 Bun 的 SQLite 驱动,提供类型安全的数据库访问。
bun add drizzle-orm
bun add -D drizzle-kit
// src/db/schema.ts
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
export const users = sqliteTable("users", {
id: integer("id").primaryKey({ autoIncrement: true }),
name: text("name").notNull(),
email: text("email").notNull().unique(),
createdAt: integer("created_at", { mode: "timestamp" })
.notNull()
.default(sql`(unixepoch())`),
});
export const posts = sqliteTable("posts", {
id: integer("id").primaryKey({ autoIncrement: true }),
title: text("title").notNull(),
content: text("content"),
authorId: integer("author_id")
.notNull()
.references(() => users.id),
});
// src/db/index.ts
import { drizzle } from "drizzle-orm/bun-sqlite";
import { Database } from "bun:sqlite";
import * as schema from "./schema";
const sqlite = new Database("app.db");
export const db = drizzle(sqlite, { schema });
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
// drizzle.config.ts
import type { Config } from "drizzle-kit";
export default {
schema: "./src/db/schema.ts",
out: "./drizzle",
dialect: "sqlite",
dbCredentials: {
url: "./app.db",
},
} satisfies Config;
# 生成迁移
bun drizzle-kit generate
# 应用迁移
bun drizzle-kit migrate
# 直接推送模式(仅限开发)
bun drizzle-kit push
# 打开 Drizzle Studio
bun drizzle-kit studio
import { db } from "./db";
import { users, posts } from "./db/schema";
// 单条插入
const user = await db.insert(users).values({
name: "Alice",
email: "alice@example.com",
}).returning();
// 批量插入
await db.insert(users).values([
{ name: "Bob", email: "bob@example.com" },
{ name: "Charlie", email: "charlie@example.com" },
]);
// 插入或忽略
await db.insert(users)
.values({ name: "Alice", email: "alice@example.com" })
.onConflictDoNothing();
// 更新插入
await db.insert(users)
.values({ name: "Alice", email: "alice@example.com" })
.onConflictDoUpdate({
target: users.email,
set: { name: "Alice Updated" },
});
import { eq, gt, like, and, or, desc, asc } from "drizzle-orm";
// 所有行
const allUsers = await db.select().from(users);
// 带条件
const activeUsers = await db
.select()
.from(users)
.where(eq(users.status, "active"));
// 多条件
const filtered = await db
.select()
.from(users)
.where(and(
gt(users.age, 18),
like(users.name, "%Alice%")
));
// 指定列
const names = await db
.select({ name: users.name, email: users.email })
.from(users);
// 排序和限制
const topUsers = await db
.select()
.from(users)
.orderBy(desc(users.createdAt))
.limit(10);
// 首个结果
const first = await db.query.users.findFirst({
where: eq(users.id, 1),
});
// 带条件更新
await db
.update(users)
.set({ name: "Alice Updated" })
.where(eq(users.id, 1));
// 更新多个字段
await db
.update(users)
.set({
name: "New Name",
updatedAt: new Date(),
})
.where(eq(users.email, "alice@example.com"));
// 带条件删除
await db.delete(users).where(eq(users.id, 1));
// 批量删除
await db.delete(users).where(gt(users.createdAt, cutoffDate));
// schema.ts
import { relations } from "drizzle-orm";
export const usersRelations = relations(users, ({ many }) => ({
posts: many(posts),
}));
export const postsRelations = relations(posts, ({ one }) => ({
author: one(users, {
fields: [posts.authorId],
references: [users.id],
}),
}));
// 带关联查询
const usersWithPosts = await db.query.users.findMany({
with: {
posts: true,
},
});
// 嵌套关联
const detailed = await db.query.users.findFirst({
where: eq(users.id, 1),
with: {
posts: {
with: {
comments: true,
},
},
},
});
// 事务
await db.transaction(async (tx) => {
const [user] = await tx.insert(users)
.values({ name: "Alice", email: "alice@example.com" })
.returning();
await tx.insert(posts).values({
title: "First Post",
authorId: user.id,
});
});
// 出错时回滚
await db.transaction(async (tx) => {
await tx.insert(users).values({ name: "Bob" });
if (someCondition) {
tx.rollback(); // 抛出异常以回滚
}
await tx.insert(posts).values({ ... });
});
// 创建预处理语句
const getUserById = db
.select()
.from(users)
.where(eq(users.id, sql.placeholder("id")))
.prepare();
// 带参数执行
const user = await getUserById.execute({ id: 1 });
// 复用以提高性能
for (const id of userIds) {
const user = await getUserById.execute({ id });
processUser(user);
}
import { sql } from "drizzle-orm";
// 原生查询
const result = await db.run(sql`
UPDATE users SET last_login = ${new Date()} WHERE id = ${userId}
`);
// 在查询中使用
const users = await db.select({
name: users.name,
upperName: sql<string>`UPPER(${users.name})`,
}).from(users);
// 在 where 中使用原生表达式
await db.select().from(users).where(
sql`${users.age} > 18 AND ${users.status} = 'active'`
);
import {
sqliteTable,
text,
integer,
real,
blob,
numeric,
} from "drizzle-orm/sqlite-core";
const example = sqliteTable("example", {
// 整数
id: integer("id").primaryKey(),
age: integer("age"),
// 文本
name: text("name"),
status: text("status", { enum: ["active", "inactive"] }),
// 实数(浮点数)
price: real("price"),
// 二进制大对象
data: blob("data", { mode: "buffer" }),
// 布尔值(存储为整数)
active: integer("active", { mode: "boolean" }),
// 时间戳(存储为整数)
createdAt: integer("created_at", { mode: "timestamp" }),
updatedMs: integer("updated_ms", { mode: "timestamp_ms" }),
// JSON(存储为文本)
metadata: text("metadata", { mode: "json" }),
});
| 错误 | 原因 | 解决方案 |
|---|---|---|
SQLITE_CONSTRAINT | 外键/唯一约束冲突 | 检查约束条件 |
no such column | 模式不匹配 | 运行迁移 |
Cannot find module | 缺少驱动 | 使用 drizzle-orm/bun-sqlite |
| 类型不匹配 | 列类型错误 | 检查模式定义 |
在以下情况加载 references/migrations.md:
在以下情况加载 references/performance.md:
每周安装量
–
代码仓库
GitHub 星标数
93
首次出现时间
–
安全审计
Drizzle ORM provides type-safe database access with Bun's SQLite driver.
bun add drizzle-orm
bun add -D drizzle-kit
// src/db/schema.ts
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
export const users = sqliteTable("users", {
id: integer("id").primaryKey({ autoIncrement: true }),
name: text("name").notNull(),
email: text("email").notNull().unique(),
createdAt: integer("created_at", { mode: "timestamp" })
.notNull()
.default(sql`(unixepoch())`),
});
export const posts = sqliteTable("posts", {
id: integer("id").primaryKey({ autoIncrement: true }),
title: text("title").notNull(),
content: text("content"),
authorId: integer("author_id")
.notNull()
.references(() => users.id),
});
// src/db/index.ts
import { drizzle } from "drizzle-orm/bun-sqlite";
import { Database } from "bun:sqlite";
import * as schema from "./schema";
const sqlite = new Database("app.db");
export const db = drizzle(sqlite, { schema });
// drizzle.config.ts
import type { Config } from "drizzle-kit";
export default {
schema: "./src/db/schema.ts",
out: "./drizzle",
dialect: "sqlite",
dbCredentials: {
url: "./app.db",
},
} satisfies Config;
# Generate migration
bun drizzle-kit generate
# Apply migrations
bun drizzle-kit migrate
# Push schema directly (dev only)
bun drizzle-kit push
# Open Drizzle Studio
bun drizzle-kit studio
import { db } from "./db";
import { users, posts } from "./db/schema";
// Single insert
const user = await db.insert(users).values({
name: "Alice",
email: "alice@example.com",
}).returning();
// Multiple insert
await db.insert(users).values([
{ name: "Bob", email: "bob@example.com" },
{ name: "Charlie", email: "charlie@example.com" },
]);
// Insert or ignore
await db.insert(users)
.values({ name: "Alice", email: "alice@example.com" })
.onConflictDoNothing();
// Upsert
await db.insert(users)
.values({ name: "Alice", email: "alice@example.com" })
.onConflictDoUpdate({
target: users.email,
set: { name: "Alice Updated" },
});
import { eq, gt, like, and, or, desc, asc } from "drizzle-orm";
// All rows
const allUsers = await db.select().from(users);
// With conditions
const activeUsers = await db
.select()
.from(users)
.where(eq(users.status, "active"));
// Multiple conditions
const filtered = await db
.select()
.from(users)
.where(and(
gt(users.age, 18),
like(users.name, "%Alice%")
));
// Specific columns
const names = await db
.select({ name: users.name, email: users.email })
.from(users);
// Order and limit
const topUsers = await db
.select()
.from(users)
.orderBy(desc(users.createdAt))
.limit(10);
// First result
const first = await db.query.users.findFirst({
where: eq(users.id, 1),
});
// Update with condition
await db
.update(users)
.set({ name: "Alice Updated" })
.where(eq(users.id, 1));
// Update multiple fields
await db
.update(users)
.set({
name: "New Name",
updatedAt: new Date(),
})
.where(eq(users.email, "alice@example.com"));
// Delete with condition
await db.delete(users).where(eq(users.id, 1));
// Delete multiple
await db.delete(users).where(gt(users.createdAt, cutoffDate));
// schema.ts
import { relations } from "drizzle-orm";
export const usersRelations = relations(users, ({ many }) => ({
posts: many(posts),
}));
export const postsRelations = relations(posts, ({ one }) => ({
author: one(users, {
fields: [posts.authorId],
references: [users.id],
}),
}));
// Query with relations
const usersWithPosts = await db.query.users.findMany({
with: {
posts: true,
},
});
// Nested relations
const detailed = await db.query.users.findFirst({
where: eq(users.id, 1),
with: {
posts: {
with: {
comments: true,
},
},
},
});
// Transaction
await db.transaction(async (tx) => {
const [user] = await tx.insert(users)
.values({ name: "Alice", email: "alice@example.com" })
.returning();
await tx.insert(posts).values({
title: "First Post",
authorId: user.id,
});
});
// Rollback on error
await db.transaction(async (tx) => {
await tx.insert(users).values({ name: "Bob" });
if (someCondition) {
tx.rollback(); // Throws to rollback
}
await tx.insert(posts).values({ ... });
});
// Create prepared statement
const getUserById = db
.select()
.from(users)
.where(eq(users.id, sql.placeholder("id")))
.prepare();
// Execute with parameter
const user = await getUserById.execute({ id: 1 });
// Reuse for performance
for (const id of userIds) {
const user = await getUserById.execute({ id });
processUser(user);
}
import { sql } from "drizzle-orm";
// Raw query
const result = await db.run(sql`
UPDATE users SET last_login = ${new Date()} WHERE id = ${userId}
`);
// In select
const users = await db.select({
name: users.name,
upperName: sql<string>`UPPER(${users.name})`,
}).from(users);
// Raw expressions in where
await db.select().from(users).where(
sql`${users.age} > 18 AND ${users.status} = 'active'`
);
import {
sqliteTable,
text,
integer,
real,
blob,
numeric,
} from "drizzle-orm/sqlite-core";
const example = sqliteTable("example", {
// Integer
id: integer("id").primaryKey(),
age: integer("age"),
// Text
name: text("name"),
status: text("status", { enum: ["active", "inactive"] }),
// Real (float)
price: real("price"),
// Blob
data: blob("data", { mode: "buffer" }),
// Boolean (stored as integer)
active: integer("active", { mode: "boolean" }),
// Timestamp (stored as integer)
createdAt: integer("created_at", { mode: "timestamp" }),
updatedMs: integer("updated_ms", { mode: "timestamp_ms" }),
// JSON (stored as text)
metadata: text("metadata", { mode: "json" }),
});
| Error | Cause | Fix |
|---|---|---|
SQLITE_CONSTRAINT | FK/unique violation | Check constraints |
no such column | Schema mismatch | Run migrations |
Cannot find module | Missing driver | Use drizzle-orm/bun-sqlite |
| Type mismatch | Wrong column type | Check schema definition |
Load references/migrations.md when:
Load references/performance.md when:
Weekly Installs
–
Repository
GitHub Stars
93
First Seen
–
Security Audits
Graft 框架:一次定义,同时提供 HTTP 和 MCP 服务的 API 开发与代理工具
916 周安装