Neon 是一个完全托管的无服务器 Postgres,将计算和存储分离,提供自动扩展、分支和无限存储等功能。可以直接使用 @neondatabase/serverless 驱动或通过像 Drizzle 这样的 ORM 在 Bun 中使用 Neon。
Drizzle ORM 支持类似 SQL 的"查询构建器"API 和类似 ORM 的 Queries API。首先创建一个项目目录,使用 bun init 初始化目录,然后安装 Drizzle 和 Neon 无服务器驱动。
mkdir bun-drizzle-neon
cd bun-drizzle-neon
bun init -y
bun add drizzle-orm @neondatabase/serverless
bun add -D drizzle-kit创建一个 .env.local 文件并添加你的 Neon Postgres 连接字符串。
DATABASE_URL=postgresql://usertitle:password@ep-adj-noun-guid.us-east-1.aws.neon.tech/neondb?sslmode=require我们将使用 Neon 无服务器驱动连接到 Neon 数据库,并封装在 Drizzle 数据库实例中。
import { neon } from "@neondatabase/serverless";
import { drizzle } from "drizzle-orm/neon-http";
// Bun 会自动从 .env.local 加载 DATABASE_URL
// 请参阅:https://bun.com/docs/runtime/environment-variables 获取更多信息
const sql = neon(process.env.DATABASE_URL!);
export const db = drizzle(sql);要查看数据库的实际效果,将这些行添加到 index.ts。
import { db } from "./db";
import { sql } from "drizzle-orm";
const query = sql`select 'hello world' as text`;
const result = await db.execute(query);
console.log(result.rows);然后使用 Bun 运行 index.ts。
bun run index.ts[
{
text: "hello world",
}
]我们可以使用 Drizzle ORM 原语为数据库定义一个模式。创建一个 schema.ts 文件并添加此代码。
import { pgTable, integer, serial, text, timestamp } from "drizzle-orm/pg-core";
export const authors = pgTable("authors", {
id: serial("id").primaryKey(),
title: text("name").notNull(),
bio: text("bio"),
createdAt: timestamp("created_at").notNull().defaultNow(),
});然后我们使用 drizzle-kit CLI 生成初始 SQL 迁移。
bunx drizzle-kit generate --dialect postgresql --schema ./schema.ts --out ./drizzle这将创建一个新的 drizzle 目录,其中包含一个 .sql 迁移文件和 meta 目录。
drizzle
├── 0000_aspiring_post.sql
└── meta
├── 0000_snapshot.json
└── _journal.json我们可以使用一个简单的 migrate.ts 脚本来执行这些迁移。此脚本创建一个到 Neon 数据库的新连接,并执行 drizzle 目录中所有未执行的迁移。
import { db } from "./db";
import { migrate } from "drizzle-orm/neon-http/migrator";
const main = async () => {
try {
await migrate(db, { migrationsFolder: "drizzle" });
console.log("Migration completed");
} catch (error) {
console.error("Error during migration:", error);
process.exit(1);
}
};
main();我们可以使用 bun 运行此脚本来执行迁移。
bun run migrate.tsMigration completed现在我们可以向数据库添加一些数据。创建一个 seed.ts 文件,内容如下。
import { db } from "./db";
import * as schema from "./schema";
async function seed() {
await db.insert(schema.authors).values([
{
title: "J.R.R. Tolkien",
bio: "The creator of Middle-earth and author of The Lord of the Rings.",
},
{
title: "George R.R. Martin",
bio: "The author of the epic fantasy series A Song of Ice and Fire.",
},
{
title: "J.K. Rowling",
bio: "The creator of the Harry Potter series.",
},
]);
}
async function main() {
try {
await seed();
console.log("Seeding completed");
} catch (error) {
console.error("Error during seeding:", error);
process.exit(1);
}
}
main();然后运行此文件。
bun run seed.tsSeeding completed现在我们有了一个带有模式和示例数据的数据库。我们可以使用 Drizzle 查询它。将 index.ts 的内容替换为以下内容。
import * as schema from "./schema";
import { db } from "./db";
const result = await db.select().from(schema.authors);
console.log(result);然后运行文件。你应该会看到我们插入的三位作者。
bun run index.ts[
{
id: 1,
title: "J.R.R. Tolkien",
bio: "The creator of Middle-earth and author of The Lord of the Rings.",
createdAt: 2024-05-11T10:28:46.029Z,
}, {
id: 2,
title: "George R.R. Martin",
bio: "The author of the epic fantasy series A Song of Ice and Fire.",
createdAt: 2024-05-11T10:28:46.029Z,
}, {
id: 3,
title: "J.K. Rowling",
bio: "The creator of the Harry Potter series.",
createdAt: 2024-05-11T10:28:46.029Z,
}
]本示例使用了 Neon 无服务器驱动的 SQL-over-HTTP 功能。Neon 的无服务器驱动还提供了 Client 和 Pool 构造函数,以支持会话、交互式事务和 node-postgres 兼容性。请参阅 Neon 文档 获取完整概述。
请参阅 Drizzle 网站 获取有关使用 Drizzle ORM 的更多文档。