TypeORM CLI:未发现数据库模式更改。

32

我正在使用NestJS和TypeORM开发一个应用程序。每当我尝试从我的实体生成迁移(通过运行typeorm migration:generate)时,我会收到以下消息:

No changes in database schema were found - cannot generate a migration. To create a new empty migration use "typeorm migration:create" command

为了排除任何可能的冲突,我甚至删除了所有现有的迁移文件(从迁移文件夹中)。

问题是在我改变应用程序模块文件夹结构后开始的:

src
 |- config
 |   |- database
 |       |- mysql
 |           |- cli-configuration.ts
 |- migrations
 |- module1
     |- controller
     |- entity
     |- service

可以看到,migrations 文件夹直接位于 src 下面,每个模块都有一个 entity 文件夹,其中放置了该模块的实体。所有 ormconfig 的设置都来自于 cli-configuration.ts 文件。

package.json 文件中,我添加了以下内容到 scripts

{
  ...
  "scripts": {
    ...
    "typeorm": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js --config src/config/database/mysql/cli-configuration.ts",
    "typeorm:migrate": "npm run typeorm migration:generate -- -n",
    "typeorm:run": "npm run typeorm migration:run"
  }
}

src/config/database/mysql/cli-configuration.ts 文件的内容是:

import * as path from 'path';
import * as dotenv from 'dotenv';

dotenv.config({
  // Path relative to project root folder (because cli command is invoked from there)
  path: path.resolve('environment', (process.env.NODE_ENV === "production") ? ".env.production" : ".env")
});

const config = {
  type: "mysql",
  host: process.env.TYPEORM_HOST,
  port: Number(process.env.TYPEORM_PORT),
  username: process.env.TYPEORM_USERNAME,
  password: process.env.TYPEORM_PASSWORD,
  database: process.env.TYPEORM_DATABASE,
  entities: [path.resolve('src', process.env.TYPEORM_ENTITIES)],

  // We are using migrations, synchronize should be set to false.
  synchronize: false,

  // Run migrations automatically,
  // you can disable this if you prefer running migration manually.
  migrationsRun: true,
  logging: process.env.TYPEORM_LOGGING,

  // Allow both start:prod and start:dev to use migrations
  // __dirname is either dist or src folder, meaning either
  // the compiled js in prod or the ts in dev.
  migrations: [path.resolve('src', process.env.TYPEORM_MIGRATIONS)],
  cli: {
    // Location of migration should be inside src folder
    // to be compiled into dist/ folder.
    // entitiesDir: process.env.TYPEORM_ENTITIES_DIR,
    migrationsDir: path.resolve('src', process.env.TYPEORM_MIGRATIONS_DIR),
    // subscribersDir: process.env.TYPEORM_SUBSCRIBERS_DIR,
  },
  dropSchema: false
};

export = config;

运行 console.log(config) 后我得到:

{
  type: 'mysql',
  host: 'localhost',
  port: 3306,
  username: 'root',
  password: 'root',
  database: 'myapp',
  entities: [ '/var/www/html/myapp/src/**/*.entity{.ts,.js}' ],
  synchronize: false,
  migrationsRun: true,
  logging: 'all',
  migrations: [ '/var/www/html/myapp/src/migrations/**/*{.ts,.js}' ],
  cli: { migrationsDir: '/var/www/html/myapp/src/migrations' },
  dropSchema: false
}

最后但同样重要的是.... 在花费了数小时来解决此问题(更改迁移和实体路径、硬编码值以及获取它们的过程.env等),我尝试执行yarn run typeorm schema:lognpm run 也可以)。当我看到我期望生成的所有迁移文件中的内容都被输出到控制台时,我感到惊讶。

CREATE TABLE `permission_permission` (`id` varchar(36) NOT NULL, `name` varchar(100) NOT NULL, `code` text NOT NULL, `create_date` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), `update_date` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), `delete_date` datetime(6) NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
CREATE TABLE `permission_role` (`id` varchar(36) NOT NULL, `name` varchar(100) NOT NULL, `code` varchar(255) NOT NULL, `create_date` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), `update_date` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), `delete_date` datetime(6) NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
CREATE TABLE `user_user` (`id` varchar(36) NOT NULL, `email` varchar(255) NOT NULL, `password` varchar(255) NOT NULL, `first_name` varchar(255) NOT NULL, `last_name` varchar(255) NOT NULL, `is_active` tinyint NOT NULL DEFAULT 0, `create_date` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), `update_date` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), `delete_date` datetime(6) NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
CREATE TABLE `permission_role_permission` (`permission_id` varchar(36) NOT NULL, `role_id` varchar(36) NOT NULL, INDEX `IDX_3247040996395a5faea3c9b3a5` (`permission_id`), INDEX `IDX_7d9cfbfd027256ab08658bcf6e` (`role_id`), PRIMARY KEY (`permission_id`, `role_id`)) ENGINE=InnoDB;
CREATE TABLE `user_user_role` (`role_id` varchar(36) NOT NULL, `user_id` varchar(36) NOT NULL, INDEX `IDX_c0c2bbb31e8e8708efc6dd5a64` (`role_id`), INDEX `IDX_beb8c39c852f4d132ba44b483c` (`user_id`), PRIMARY KEY (`role_id`, `user_id`)) ENGINE=InnoDB;
ALTER TABLE `permission_role_permission` ADD CONSTRAINT `FK_3247040996395a5faea3c9b3a54` FOREIGN KEY (`permission_id`) REFERENCES `permission_role`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
ALTER TABLE `permission_role_permission` ADD CONSTRAINT `FK_7d9cfbfd027256ab08658bcf6e1` FOREIGN KEY (`role_id`) REFERENCES `permission_permission`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
ALTER TABLE `user_user_role` ADD CONSTRAINT `FK_c0c2bbb31e8e8708efc6dd5a64b` FOREIGN KEY (`role_id`) REFERENCES `user_user`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
ALTER TABLE `user_user_role` ADD CONSTRAINT `FK_beb8c39c852f4d132ba44b483c0` FOREIGN KEY (`user_id`) REFERENCES `permission_role`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;

有谁能告诉我为什么schema:log可以检测到我的实体中的更改,但migration:generate却无法正常工作吗?


4
我有同样的问题。然而,schema:log显示“你的模式已经是最新的……” - jordiburgos
我遇到了完全相同的问题。 - Samuel Castro
1
你解决了这个问题吗?我也遇到了同样的问题,但没有什么好运气。 - ashu
6个回答

4

对我来说,这个提示很有帮助。只需在使用npm run typeorm -- migration:generate -n migration_name生成新迁移之前运行npm run build即可。某种程度上需要一个最新的dist文件夹。


我已经试图解决这个问题大约8个小时了。这就是答案。 - Cory Baker

2

我遇到了完全相同的问题,似乎是旧版本0.2.x出了问题。我一直在使用0.2.34版本,在那里我也遇到了这个问题。

更新到0.2.45版本后,问题得以解决。


0
这个问题通常是由路径出现错误引起的。 我使用您的配置和目录样式创建了一个小型的工作项目。这是链接。
https://github.com/nairi-abgaryan/typeorm-mysql-nestjs

快速概述。 稍微更新了cli-configuration.ts文件。 typeorm库将按照您在package.json中描述的方式使用此配置。

import * as dotenv from 'dotenv';
import {TypeOrmModuleOptions} from '@nestjs/typeorm/dist/interfaces/typeorm-options.interface';
dotenv.config({
   path: '.env',
});

const config: TypeOrmModuleOptions = {
  type: 'mysql',
  host: process.env.TYPEORM_HOST,
  port: Number(process.env.TYPEORM_PORT),
  username: process.env.TYPEORM_USERNAME,
  password: process.env.TYPEORM_PASSWORD,
  database: process.env.TYPEORM_DATABASE,
  autoLoadEntities: true,
  entities: [`${__dirname}/../../../../src/**/*.entity{.ts,.js}`],
  migrations: [`${__dirname}/../../../migrations`],
  cli: {
    migrationsDir: `${__dirname}/../../../migrations`,
  },
  dropSchema: false,
};

export = config;

.env

TYPEORM_TYPE='mysql'
TYPEORM_HOST=localhost
TYPEORM_PORT=3306
TYPEORM_USERNAME='root'
TYPEORM_PASSWORD='root'
TYPEORM_DATABASE='myapp'
TYPEORM_MIGRATIONS='migrations'

此外,我创建了一个ormconfig.json文件,用于nest js连接到数据库。如文档所述,当您不想在app.module中进行配置时,可以使用该文件。

请注意,ormconfig.json文件由typeorm库加载。因此,任何上述描述的额外属性(通过forRoot()方法内部支持,例如autoLoadEntities和retryDelay)将不会应用。幸运的是,TypeORM提供了getConnectionOptions函数,从ormconfig文件或环境变量中读取连接选项。通过这种方式,您仍然可以使用配置文件并设置Nest特定的选项,具体如下:

TypeOrmModule.forRootAsync({
  useFactory: async () =>
    Object.assign(await getConnectionOptions(), {
      autoLoadEntities: true,
    }),
});

0

这是我采取的步骤使其工作:

  1. 添加一个空迁移,在 up 方法中添加一个查询以删除所有表。

例如:

await queryRunner.query(DROP TABLE "table_name");

  1. 删除此迁移

  2. 删除您的 dist 文件夹

  3. 删除您的 .idea 文件夹

  4. 启动您的服务 - 我使用了 nest start(这应该会添加一个新的干净的 dist 文件夹)

  5. 检查您的 ormconfig.json 文件中的 "migrations" 位置。

我的是:

"migrations": [ "dist/database/migration/*.js" ]

检查`dist`文件夹中的路径 - 我在那里没有找到名为"migration"的文件夹。
添加文件夹`migration`(或使用`ormconfig.json`中的名称)。
像之前一样运行`migration:generate`,它应该可以工作。
希望对你有所帮助!

1
当迁移文件夹位于dist目录中时,如何帮助第一步?如果您运行yarn build,则会完全删除dist,并且在下一次运行时仍然存在相同的问题。 - Игор Ташевски

0

我们在使用Nestjs + TypeORM + PostgreSQL的项目中遇到了类似的问题。

我们发现当您设置一个与Type相同值的环境变量时,TypeORM会产生冲突。

请看以下示例:https://imgur.com/a/pgR6OGJ

在这种情况下,我们有TYPEORM_TYPE = postgrestype:'postgres'出于某种未知原因,TypeORM无法解析并找不到您的数据库。

因此,要修复它,请从.env文件中将其删除,然后再次运行!

希望我能帮助到您或其他人;)


-8
问题在于某些原因导致 migration:generate 没有被执行。尝试更改你的 package.json 脚本为 "migration:create": "npm run typeorm migration:create -n"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接