Orchid ORM 快速开始

135 阅读7分钟

Orchid ORM 提供了命令行初始化脚本,通过交互式提示引导项目配置。无论是创建全新项目,还是在现有项目中生成适配的脚手架,该工具均能安全运行 —— 不会删除任何已有文件,仅按需生成必要的配置与目录结构。

完成本节内容后,推荐阅读 构建示例应用程序 指南。该实战教程完整演示了使用 Orchid ORM 开发实际应用的全流程,涵盖环境搭建、数据库迁移、表结构定义、复杂关系查询编写、查询逻辑抽象至存储库,以及单元测试编写等核心环节,帮助开发者快速掌握框架特性与最佳实践。

无论你是要为新项目生成基础架构,还是将 Orchid ORM 集成到现有项目中,均可通过运行以下脚本完成初始化:

# 使用 npm:
npm create orchid-orm@latest
# 使用 pnpm:
pnpm create orchid-orm
# 使用 bun:
bun create orchid-orm
# 使用 yarn:
yarn create orchid-orm

该脚本将通过交互式提问完成个性化配置:

选择 Orchid ORM 安装位置?

直接按回车默认当前目录,也可输入相对 / 绝对路径或新目录名。脚本会递归创建目标目录(已有目录不会覆盖)。

TS 文件执行工具

当使用 bun 运行命令时,系统会自动跳过此配置问题并直接使用 bun。若需手动选择其他工具,则可在以下选项中进行选择:tsx、vite-node 和 ts-node。对于 tsxvite-node 和 ts-node 这三种工具,除了支持直接执行 .ts 格式的迁移文件外,脚本还会在 package.json 中自动生成专属脚本,用于将迁移文件编译为 .js 格式,并执行编译后的迁移文件。

数据库时间戳返回类型?

可选择 字符串数字 或 Date对象.此配置支持后续全局修改,也可针对单个表单独覆盖。

是否为测试添加独立数据库?(y/n)

若计划在真实数据库上运行测试,输入 y。Orchid ORM 提供专属工具:testTransaction(事务测试工具)、record factories(模拟数据工厂),简化测试编写流程。

是否集成数据验证库?(Zod/Valibot,可选)

可选集成 Zod 或 Valibot(Orchid ORM 自身不包含数据验证逻辑,需通过集成实现),具体用法见 验证方法 文档。

是否添加测试用对象工厂?(y/n)

输入 y 可启用 record factories,基于表结构自动生成模拟数据,提升测试效率。

是否添加演示表(帖子 / 评论)?(y/n)

选择 y 会自动创建示例表文件、迁移脚本及种子数据,快速体验框架功能。

回答所有问题后,脚本将自动生成项目所需的配置文件、目录结构及初始化代码,全程不影响现有文件。运行脚本后,请检查 package.json 文件并安装依赖项。

{
  "name": "project",
  // 选择 tsx、vite-node 或 bun 时,会设置 "type": "module"
  "type": "module",
  "scripts": {
    // 用于运行数据库脚本,例如 npm run db create、npm run db migrate;
    "db": "tsx src/db/dbScript.ts"
  },
  "dependencies": {
    // dotenv 会从 .env 文件中加载环境变量;
    "dotenv": "^16.0.3",
    // ORM 负责定义表及其之间的关系
    "orchid-orm": "^1.5.18",
    // 将表列转换为 Zod 模式,以便用于数据验证;
    "orchid-orm-schema-to-zod": "^0.2.18"
  },
  "devDependencies": {
    // 用于在测试中生成模拟对象;
    "orchid-orm-test-factory": "^0.2.24",
    // for the fastest typescript compilation
    "@swc/core": "^1.3.32",
    // node.js types
    "@types/node": "^18.11.18",
    "typescript": "^4.9.5",
    // for running typescript
    "tsx": "^4.1.1"
  }
}

如果当前目录中已有 tsconfig.json 文件,脚本不会对其进行修改。为确保功能正常,tsconfig.json 必须包含 target 属性且 "strict": true

使用 Vite 配置,有一个优秀的插件 vite-plugin-node,它为 Node.js 后端开发启用 热模块替换(HMR) 。如果开发服务器基于 Vite 运行,也可通过该插件捆绑并执行数据库脚本。

若在初始化时选择了 vite-nodepackage.json 中将包含以下配置:

{
  "type": "module",
  "scripts": {
    // to run db scripts
    "db": "vite-node src/db/dbScript.ts --",
    // build migrations
    "build:migrations": "vite build --config vite.migrations.mts",
    // run compiled migrations
    "db:compiled": "node dist/db/dbScript.mjs"
  },
  "devDependencies": {
    // vite bundler itself
    "vite": "^4.5.0",
    // for executing typescript
    "vite-node": "^0.34.6",
    // special plugin for compiling migrations
    "rollup-plugin-node-externals": "^6.1.2"
  }
}

注意 "type": "module" 在顶部:所有编译的文件将被视为 ES 模块。 如果您的项目依赖于 commonjs 模块,请删除 "type": "module",编译的迁移仍然可以正常工作。

Orchid ORM 的脚手架脚本不会预设项目的启动和编译方式,而是添加了独立的构建和编译迁移脚本,供您在 CI/CD 环境中使用。

在某些场景下,直接执行原始 TypeScript 迁移文件( .ts)与生产环境迁移并无差异;但在另一些场景中,您可能希望尽可能提升迁移速度 —— 编译后的 JavaScript 文件( .js)执行效率通常更高。

使用 tsx 进行配置 tsx 仅用于执行 TypeScript 代码,若需编译(将 TypeScript 转为 JavaScript),则需要借助 esbuild

如果在初始化时选择了 tsxpackage.json 中将包含以下配置:

{
  "type": "module",
  "scripts": {
    // to run db scripts
    "db": "NODE_ENV=development tsx src/db/dbScript.ts",
    // build migrations
    "build:migrations": "rimraf dist/db && node esbuild.migrations.js",
    // run compiled migrations
    "db:compiled": "NODE_ENV=production node dist/db/dbScript.js"
  },
  "devDependencies": {
    // for executing TS
    "tsx": "^4.1.1",
    // for compiling
    "esbuild": "^0.19.5",
    // to clean dist directory
    "rimraf": "^5.0.5"
  }
}

注意 "type": "module" 需位于文件顶部:所有编译后的文件将被视为 ES 模块。若项目依赖 CommonJS 模块,可删除 "type": "module",此时编译后的迁移脚本仍能正常运行。

创建的项目结构如下:

.
├── src/
│   └── db/
│       ├── migrations/ - 包含可执行迁移或回滚的迁移文件。
│       │   ├── timestamp_createPost.ts
│       │   └── timestamp_createComment.ts
│       ├── tables/ - 存放应用中使用的表,在此定义列和关系.
│       │   ├── comment.table.ts
│       │   └── post.table.ts
│       ├── baseTable.ts - 用于定义列类型覆盖(如时间戳返回格式等全局或表级配置)。
│       ├── config.ts - 导出数据库凭证(如连接字符串、认证信息等)。
│       ├── db.ts - ORM 核心文件,将所有表连接为一个供全局调用。
│       ├── dbScript.ts - 由 npm run db *command* 运行的脚本,封装数据库操作命令(如迁移、回滚、种子数据填充)。
│       └── seed.ts - 用于向表中填充初始化数据(如测试数据、默认配置)
├── .env - 存放数据库凭证(如 DATABASE_URL),需通过 .gitignore 排除以免泄露。
├── .gitignore - 必须忽略 .env 文件,避免敏感信息提交到版本控制。
├── package.json
└── tsconfig.json - 指定严格模式(strict: true)至关重要,确保 TypeScript 类型检查的严谨性。

修改 .env 文件中的数据库凭证:

DATABASE_URL=postgres://user:password@localhost:5432/dbname?ssl=true|false

# 如果您希望有一个单独的测试数据库
DATABASE_TEST_URL=postgres://user:password@localhost:5432/dbname-test?ssl=true|false

默认情况下使用 public 数据库模式,您可以通过在数据库连接 URL 中附加 schema 参数来更改它:

DATABASE_URL=postgres://user:password@localhost:5432/dbname?schema=customSchemaName

如果您使用的是托管数据库,请将上述配置中的 ssl 设置为 true

若使用托管数据库,数据库已由服务提供商创建好。但如果您是使用本地的 PostgreSQL 进行开发,请使用以下命令来创建数据库:

# command to create a database:
npm run db create

默认情况下,数据库中的列使用 camelCase 命名。

如果您希望数据库中使用 snake_case(应用程序端仍会保持 camelCase 命名),请在 src/db/baseTable.ts 中设置 snakeCase: true 选项:

// src/db/baseTable.ts

export const BaseTable = createBaseTable({
  snakeCase: true,
  // ...snip
});

// to use later for custom raw SQL expressions
export const { sql } = BaseTable;

如果您选择创建演示表,那么在 src/db/migrations 目录下会有迁移文件。可运行以下命令来执行迁移:

# command to run migrations (create tables):
npm run db up

运行演示表的种子数据填充:

npm run db seed

至此,所有设置已全部完成。接下来,您可以开始创建自己的表并编写查询语句。

若要创建新的数据库表,您有以下几种方式可供选择:

  • 若您已有一个包含表的现有数据库,可使用 db pull 命令为这些表生成代码
  • 在代码中定义新表,并为其生成迁移。
  • 您也可以创建一个新的迁移文件,然后手动编写迁移代码。

示例

// src/hello.ts
import { db } from './db';

const main = async () => {
  // load all records
  const records = await db.sample;

  // load first record
  const first = await db.sample.take();

  // select, where, order, limit, offset, etc
  const result = await db.sample
    .select('id', 'name')
    .where({ name: 'name' })
    .order({ name: 'DESC' })
    .limit(10)
    .offset(10);

  // find by id
  const recordById = await db.sample.find(123);

  // find one by conditions
  const record = await db.sample.findBy({ name: 'name' });
};

main();