TypeORM无法生成迁移:未检测到数据库架构变更求助
无法让TypeORM生成迁移的排查与解决
问题描述
查阅了近100篇Stack Overflow帖子、数十篇Reddit帖子,还观看了若干YouTube视频,但始终无法让TypeORM生成迁移。确定问题出在实体glob路径未匹配到实体,但尝试所有方法都无效。
数据源文件(data-source.ts)
import { DataSource, DataSourceOptions } from "typeorm"; export const dataSourceOptions: DataSourceOptions = { type: 'postgres', host: 'localhost', port: 5432, username: 'postgres', password: 'example', database: 'postgres', migrations: ['.src/migrations/*{.ts,.js}'], // entities: ['src/entities/*{.ts,.js}'], // entities: ['./src/entities/*{.ts,.js}'], // entities: ['dist/src/entities/*{.ts,.js}'], // entities: ['./dist/src/entities/*{.ts,.js}'], // entities: [`${__dirname}/src/entities/*{.ts,.js}`], // entities: [`${__dirname}/dist/src/entities/*{.ts,.js}`], // entities: [Item,Brand,Product,Size,Value], // 已添加对应导入语句 entities: ['dist/src/entities/*{.ts,.js}'], } const dataSource = new DataSource(dataSourceOptions); export default dataSource;
注释部分为尝试过的各种实体路径配置。
项目结构
project-name ├──data-source.ts ├──src │ └──entities │ ├──item.js │ ├──brand.js │ ├──size.js │ ├──value.js │ └──product.js
实体示例(product.js)
import { Entity, Column, PrimaryGeneratedColumn, ManyToOne, JoinColumn } from 'typeorm'; import { Brand } from './brand'; @Entity() export class Product { @PrimaryGeneratedColumn("uuid") id: string; @Column() msrp: number; @Column() name: string; @ManyToOne(type => Brand) @JoinColumn({ name: "brand" }) brand: Brand; }
环境与操作
- 通过Nest的
synchronize可以正常运行应用,但清空数据库后尝试生成迁移仍失败:
> docker exec -it 0dcfd4457db2 sh # psql -U postgres psql (15.2 (Debian 15.2-1.pgdg110+1)) Type "help" for help. postgres=# \dt Did not find any relations. postgres=# \d Did not find any relations.
- 依赖配置:
"dependencies": { "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.3.1", "@nestjs/core": "^9.0.0", "@nestjs/mapped-types": "*", "@nestjs/platform-express": "^9.0.0", "@nestjs/typeorm": "^9.0.1", "pg": "^8.10.0", "reflect-metadata": "^0.1.13", "rxjs": "^7.2.0", "typeorm": "^0.3.12" }, "devDependencies": { "@nestjs/cli": "^9.0.0", "@nestjs/schematics": "^9.0.0", "@nestjs/testing": "^9.0.0", "@types/express": "^4.17.13", "@types/jest": "29.2.4", "@types/node": "18.11.18", "@types/supertest": "^2.0.11", "@typescript-eslint/eslint-plugin": "^5.0.0", "@typescript-eslint/parser": "^5.0.0", "eslint": "^8.0.1", "eslint-config-prettier": "^8.3.0", "eslint-plugin-prettier": "^4.0.0", "jest": "29.3.1", "prettier": "^2.3.2", "source-map-support": "^0.5.20", "supertest": "^6.1.3", "ts-jest": "29.0.3", "ts-loader": "^9.2.3", "ts-node": "^10.9.1", "tsconfig-paths": "4.1.1", "typescript": "^4.7.4" },
- 尝试过的CLI命令与脚本:
npx typeorm、typeorm-ts-node-esm、typeorm-ts-node-commonjs- package.json脚本:
"typeorm": "npm run build && npx typeorm -d ./data-source.js""typeorm": "./node_modules/.bin/ts-node ./node_modules/.bin/typeorm""typeorm": "node --require ts-node/register ./node_modules/typeorm/cli.js"
- 所有未报错的尝试最终均返回:
未发现数据库架构变更 - 无法生成迁移。
解决方案
1. 修正实体路径匹配逻辑
从项目结构看,data-source.ts位于项目根目录,src/entities下是.js文件,当前配置的dist/src/entities/*{.ts,.js}存在路径歧义:
- 若未执行
npm run build,dist目录不存在;即使编译后,也只需匹配.js文件 - 尝试以下路径配置:
- 直接用相对路径指向源码实体(适合ts-node运行CLI):
entities: ['./src/entities/**/*.js'] - 用
__dirname确保路径绝对正确:entities: [`${__dirname}/src/entities/**/*.js`] - 若使用编译后的文件,先执行
npm run build,再配置:entities: [`${__dirname}/dist/src/entities/**/*.js`]
- 直接用相对路径指向源码实体(适合ts-node运行CLI):
2. 匹配CLI命令与数据源模块类型
TypeORM 0.3+版本要求CLI必须匹配项目模块类型:
- 若项目是CommonJS(tsconfig.json中
module: "CommonJS"),执行:npx typeorm-ts-node-commonjs migration:generate src/migrations/InitialSchema -d ./data-source.ts - 若项目是ESM(
module: "ESNext"),执行:npx typeorm-ts-node-esm migration:generate src/migrations/InitialSchema -d ./data-source.ts - 优先直接使用ts文件配合ts-node,避免编译后用js文件的路径问题
3. 验证实体加载状态
在data-source.ts末尾添加代码,确认实体是否被正确加载:
dataSource.initialize().then(() => { console.log('数据源初始化成功'); console.log('已加载的实体:', dataSource.entityMetadatas.map(meta => meta.name)); }).catch(err => { console.error('数据源初始化失败:', err); });
运行ts-node data-source.ts,若实体列表为空,继续调整路径;若有实体,再尝试生成迁移。
4. 清除TypeORM缓存
TypeORM可能缓存实体信息,执行以下命令清除缓存:
rm -rf node_modules/.cache/typeorm
5. 检查实体装饰器与引用
确保所有实体都添加了@Entity()装饰器,相互引用的实体(如Product和Brand)导入路径正确,无循环引用问题。
内容的提问来源于stack exchange,提问作者kure
相关产品推荐
相关产品推荐

