TypeORM 命令行工具(CLI)完全指南:从初始化到迁移与 Schema 同步
本篇技术指南系统讲解 TypeORM 内置 CLI 的安装、配置与全部核心命令。无论你是刚刚开始搭建项目、需要创建实体与订阅者,还是要在生产环境执行迁移与 Schema 管理,都能在文中找到可复制的命令与配套的源码级原理说明。读完本文,你将掌握 typeorm init、entity:create、subscriber:create、migration:*、schema:*、query、cache:clear 与 version 的完整用法,并理解它们在 TypeORM 内部的实际执行链路。
TypeORM 的 CLI 是一个基于 yargs 构建的命令行程序,入口文件为 src/cli.ts,它注册了 14 个命令模块,并启用了 strict()(未知命令报错)与 demandCommand(1)(必须提供命令)等严格校验。所有命令的实现都位于 src/commands 目录,下文逐一展开。
安装 CLI
实体文件为 JavaScript 时
TypeORM CLI 本身由 JavaScript 编写并运行于 Node 环境。如果你的实体文件是 JavaScript,直接全局安装即可:
npm i -g typeorm
如果你不想全局安装,也可以对每条命令使用 npx typeorm <params> 临时调用:
npx typeorm --help
一个值得注意的坑:如果你项目本地还装了一份 typeorm,请确保本地版本与将要安装的全局版本一致,避免 CLI 与运行时行为不一致(typeorm version 命令会专门帮你检测这一点,详见下文)。
实体文件为 TypeScript 时
CLI 在 Node 中运行,无法直接读取 TypeScript 实体。如果你的实体文件是 TypeScript,需要先将其转译为 JavaScript 再使用 CLI(仅使用 JavaScript 的读者可跳过本节)。
更省事的方式是在项目中配置 ts-node,让 CLI 直接通过 ts-node 加载 TS 文件。步骤如下:
- 安装 ts-node 作为开发依赖:
npm install ts-node --save-dev
- 在
package.json的scripts中加入 typeorm 命令。CommonJS 项目使用:
"scripts": {
...
"typeorm": "typeorm-ts-node-commonjs"
}
- ESM 项目则换成:
"scripts": {
...
"typeorm": "typeorm-ts-node-esm"
}
对应的两个可执行入口分别实现于 src/cli-ts-node-commonjs.ts 与 src/cli-ts-node-esm.ts,它们会在加载 CLI 前先挂载 ts-node 的 CommonJS/ESM 寄存器。
如果你还想加载更多模块(例如路径别名类模块 module-alias),可以通过追加 --require my-module-supporting-register 的方式预先注册:
npm run typeorm migration:run -- --require my-module-supporting-register -d path-to-datasource-config
配置完成后,即可这样执行命令(注意 -- 后的参数会透传给 CLI):
npm run typeorm migration:run -- -d path-to-datasource-config
如何阅读本文档的命令示例
为了减少行文冗长,下文所有示例统一使用全局安装的 typeorm 命令开头。根据你自己的安装方式,可以将命令开头的 typeorm 替换为 npx typeorm 或 npm run typeorm(后者记得用 -- 分隔参数),效果完全一致。
初始化一个新的 TypeORM 项目
typeorm init 是搭建 TypeORM 项目最快的方式。执行:
typeorm init
从 InitCommand.ts 的源码实现可以看到,它会在当前目录生成一个基础项目所需的全部文件,当前版本实际生成的内容包括:
.gitignore(默认忽略.idea/、.vscode/、node_modules/、build/等)package.json(自动注入reflect-metadata、typeorm及对应数据库驱动依赖,并配置好start与typeormscripts)README.md(包含运行步骤说明)tsconfig.json(按 CommonJS/ESM 生成对应配置,默认开启experimentalDecorators与emitDecoratorMetadata)src/entities/User.ts(示例实体 User)src/data-source.ts(AppDataSource实例,内含所选数据库的连接配置模板)src/index.ts(应用入口示例)src/migrations/目录
生成后依次执行:
npm install # 安装全部依赖
npm start # 运行应用
所有文件默认生成在当前目录。如果想生成到指定目录,使用 --name:
typeorm init --name my-project
指定数据库类型使用 --database(源码中的合法取值包括 postgres、mysql、mariadb、better-sqlite3、mssql、oracle、mongodb、cockroachdb、spanner,未指定时默认 postgres):
typeorm init --database mssql
生成 ESM 基础项目使用 --module esm(--module 的合法取值为 commonjs 与 esm,默认 commonjs):
typeorm init --name my-project --module esm
生成带 Express 示例代码的项目使用 --express,此时会额外生成 src/routes.ts 与 src/controllers/UserController.ts(内置基于 AppDataSource.getRepository(User) 的增删查改 REST 接口):
typeorm init --name my-project --express
如果你使用 Docker,可以加 --docker 一并生成 docker-compose.yml。从 getDockerComposeTemplate 的实现可见,不同数据库会生成对应的容器编排:postgres 17、mysql 9、mariadb 11.7、mssql 2022、mongo 8、cockroachdb v25、spanner 模拟器等;但 better-sqlite3(SQLite 无需 docker)与 oracle(暂未实现)会直接抛出错误:
typeorm init --docker
typeorm init 是搭建 TypeORM 项目最省事的途径,生成的 data-source.ts 模板随数据库不同而预填了对应的 host、port、username、password、database 等连接参数(如 mysql 默认 3306、postgres 默认 5432、mssql 使用 sa/Admin12345),拿到后只需按你的实际环境微调即可。
创建实体
使用 CLI 创建新实体:
typeorm entity:create path-to-entity-dir/entity
从 EntityCreateCommand.ts 的实现看,该命令会把 path 解析为绝对路径,并以路径中的文件名为类名,生成一个带 @Entity() 装饰器的空类骨架(自动追加 .ts 扩展名);如果目标文件已存在会报错 File "...ts" already exists。例如:
typeorm entity:create src/entity/Post
将生成 src/entity/Post.ts:
import { Entity } from "typeorm"
@Entity()
export class Post {
}
实体定义的具体语法(列、索引、关系、嵌入实体等)参见 实体文档。
创建订阅者
使用 CLI 创建新的订阅者:
typeorm subscriber:create path-to-subscriber-dir/subscriber
与实体创建类似,SubscriberCreateCommand.ts 会生成一个实现了 EntitySubscriberInterface、标注了 @EventSubscriber() 的空订阅者骨架:
import { EventSubscriber, EntitySubscriberInterface } from "typeorm"
@EventSubscriber()
export class Subscriber implements EntitySubscriberInterface {
}
订阅者的监听时机(afterInsert、beforeUpdate 等)与完整用法参见 监听器与订阅者文档。
管理迁移
TypeORM CLI 提供了一整套迁移生命周期命令,下表汇总了各命令的用途:
| 命令 | 用途 |
|---|---|
typeorm migration:create |
创建空的迁移文件 |
typeorm migration:generate |
对比实体与数据库实际结构,生成迁移 |
typeorm migration:run |
执行所有待执行的迁移 |
typeorm migration:revert |
回滚最后一次执行的迁移 |
typeorm migration:show |
列出所有迁移及其执行状态 |
迁移的整体概念与原理参见 迁移文档。
创建空迁移:migration:create
typeorm migration:create path-to-migrations-dir/ClassName
从 MigrationCreateCommand.ts 可见,该命令会以「时间戳 + 类名」的形式生成迁移文件(默认生成 TypeScript,文件名如 1730000000000-ClassName.ts),类名由路径中的文件名转换而来,并内置空的 up / down 方法。它还支持以下参数:
-o, --outputJs:生成 JavaScript 版本而非 TypeScript--esm:以 ESM 语法导出(配合-o使用,输出export class而非module.exports =)-t, --timestamp:自定义迁移时间戳
空迁移的编写(如何在 up 中使用 queryRunner.query(...))参见 创建迁移。
根据实体差异生成迁移:migration:generate
typeorm migration:generate path-to-migrations-dir/ClassName -d path-to-datasource-config
这是最有价值也最常用的迁移命令:它通过指定的 DataSource 连接数据库,把当前实体元数据与实际数据库 Schema 做对比,自动生成包含 up / down SQL 的迁移文件。其核心原理在 MigrationGenerateCommand.ts 中:命令先通过 CommandUtils.loadDataSource 加载 DataSource,并强制关闭 synchronize、migrationsRun、dropSchema 与 logging,随后调用 dataSource.driver.createSchemaBuilder().log() 拿到需要执行的 upQueries 与 downQueries,再将其逐条包装为 await queryRunner.query(...) 写入迁移文件。
该命令支持的参数包括:
-d, --dataSource:必填,指向定义 DataSource 实例的文件路径-p, --pretty:对生成的 SQL 做美化缩进(基于 sql formatter)-o, --outputJs:生成 JavaScript 迁移--esm:配合-o输出 ESM 语法-dr, --dryrun:只在控制台打印迁移内容而不写入文件-ch, --check:校验模式——若数据库与实体完全一致则打印 "No changes..." 并以退出码 0 结束;若有差异则打印差异并退出码 1(适合集成进 CI 防止 Schema 漂移)-t, --timestamp:自定义时间戳
当检测不到任何 Schema 差异时,命令会提示无法生成迁移,并建议改用 typeorm migration:create 创建空迁移。生成的迁移内部实现细节参见 生成迁移。
执行迁移:migration:run
typeorm migration:run -d path-to-datasource-config
MigrationRunCommand.ts 会加载 DataSource(同时把日志级别设为 ["query", "error", "schema"],方便观察执行的 SQL),然后调用 dataSource.runMigrations(options) 执行所有尚未执行的迁移。支持参数:
-d, --dataSource:必填-t, --transaction:迁移事务策略,取值default(遵循 DataSource 的migrationsTransactionMode,默认all)、all、none、each-f, --fake:标记迁移为已执行但不真正运行 SQL(适用于 Schema 已被外部手工/其他项目改过的场景)
回滚迁移:migration:revert
typeorm migration:revert -d path-to-datasource-config
MigrationRevertCommand.ts 通过 dataSource.undoLastMigration(options) 回滚最近一次执行的迁移(即执行该迁移的 down 方法),支持与 migration:run 相同的 -t, --transaction 与 -f, --fake 参数。注意它一次只回滚一条。
查看迁移状态:migration:show
typeorm migration:show -d path-to-datasource-config
MigrationShowCommand.ts 调用 dataSource.showMigrations(),以表格形式列出所有迁移及其执行状态([X] 表示已执行,[ ] 表示待执行),便于排查迁移遗漏。
迁移的完整执行、回滚与状态说明参见 执行迁移、回滚迁移 与 查看迁移状态。
同步数据库 Schema
typeorm schema:sync 会根据实体定义直接对数据库执行 Schema 变更(相当于在运行时开启 synchronize: true 的效果):
typeorm schema:sync -d path-to-datasource-config
从 SchemaSyncCommand.ts 的实现可见,它加载 DataSource 后调用 dataSource.synchronize(),自动执行建表、加列、建索引等 SQL。
⚠️ 生产环境请谨慎使用:
schema:sync可能造成数据丢失(例如删除实体中已移除的列或表)。在生产环境执行前,务必先用下面的schema:log检查它将要运行哪些 SQL。
预览 Schema 同步 SQL(不实际执行)
typeorm schema:log 用于查看 schema:sync 将要执行的 SQL,而不会真正执行它们:
typeorm schema:log -d path-to-datasource-config
SchemaLogCommand.ts 内部同样调用 dataSource.driver.createSchemaBuilder().log() 收集 upQueries,并打印「Schema synchronization will execute following sql queries (N):」的分隔线及高亮 SQL;如果 Schema 已是最新,则提示 "Your schema is up to date - there are no queries to be executed by schema synchronization."。这也是 migration:generate 对比差异的同一底层机制,是上线前检查变更的最佳工具。
删除数据库 Schema
typeorm schema:drop 会删除数据库中的全部表:
typeorm schema:drop -d path-to-datasource-config
SchemaDropCommand.ts 内部调用 dataSource.dropDatabase()。该命令会彻底移除数据库中的数据,生产环境务必极度谨慎。
执行任意 SQL 查询
typeorm query 可以直接在目标数据库上执行任意 SQL:
typeorm query "SELECT * FROM USERS" -d path-to-datasource-config
QueryCommand.ts 会先高亮打印将要执行的 SQL,然后通过 dataSource.createQueryRunner() 创建 QueryRunner 并执行查询,最后以 console.dir 打印结果;若无返回结果则提示 "Query has been executed. No result was returned."。
清理查询缓存
如果你在 QueryBuilder 中使用了缓存(cache: true 或 cache: { id, milliseconds }),有时需要手动清空缓存中存储的所有内容:
typeorm cache:clear -d path-to-datasource-config
CacheClearCommand.ts 会先检查 DataSource 是否配置了 queryResultCache,若未启用缓存会提示 "Cache is not enabled. To use cache enable it in connection configuration.";启用时则调用 dataSource.queryResultCache.clear() 完成清空。
查看版本
typeorm version 会同时显示你本地与全局安装的 TypeORM 版本:
typeorm version
VersionCommand.ts 通过执行 npm list --depth=0 与 npm list -g --depth=0 分别探测本地与全局版本,若两者都存在且不一致,会给出提示:「To avoid issues with CLI please make sure your global and local TypeORM versions match, or you are using locally installed TypeORM instead of global one.」——这正是本文开头强调「本地与全局版本保持一致」的自动化校验手段。
常用命令速查表
| 命令 | 作用 | 必填参数 |
|---|---|---|
typeorm init |
生成 TypeORM 基础项目 | 无 |
typeorm entity:create <path> |
创建实体骨架 | path |
typeorm subscriber:create <path> |
创建订阅者骨架 | path |
typeorm migration:create <path> |
创建空迁移 | path |
typeorm migration:generate <path> |
根据实体差异生成迁移 | path、-d |
typeorm migration:run |
执行待运行迁移 | -d |
typeorm migration:revert |
回滚最近迁移 | -d |
typeorm migration:show |
查看迁移状态 | -d |
typeorm schema:sync |
同步 Schema 到数据库 | -d |
typeorm schema:log |
预览同步 SQL | -d |
typeorm schema:drop |
删除全部表 | -d |
typeorm query "<SQL>" |
执行任意 SQL | -d |
typeorm cache:clear |
清空查询缓存 | -d |
typeorm version |
打印本地/全局版本 | 无 |
需要再次提醒的是:以上示例均以全局 typeorm 命令书写;若你通过 npx typeorm 或 npm run typeorm 调用,请按本文「如何阅读本文档的命令示例」一节做对应替换。所有命令的完整注册与校验逻辑可参阅 src/cli.ts 及 src/commands 目录下的各命令实现。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00