【问题标题】:Typeorm 0.3 migration generates changes even without making a single change to the entities即使不对实体进行任何更改,Typeorm 0.3 迁移也会生成更改
【发布时间】:2023-01-13 05:44:35
【问题描述】:

自从我升级到 TypeORM 0.3 后,我遇到了一个奇怪的错误,我生成了我的第一次迁移,因为数据库是空的,并且它是正确生成的。如果我之后生成第二次迁移,而不对实体进行任何更改,则生成的迁移会识别每个表上的更改,使用这样的脚本

await queryRunner.query(`ALTER TABLE \`clients\` CHANGE \`deletedAt\` \`deletedAt\` datetime(6) NULL`);
await queryRunner.query(`ALTER TABLE \`clients\` CHANGE \`type\` \`type\` varchar(255) NULL`);
await queryRunner.query(`ALTER TABLE \`clients\` CHANGE \`first_name\` \`first_name\` varchar(255) NULL`);
await queryRunner.query(`ALTER TABLE \`clients\` CHANGE \`last_name\` \`last_name\` varchar(255) NULL`);
await queryRunner.query(`ALTER TABLE \`clients\` CHANGE \`company_name\` \`company_name\` varchar(255) NULL`);
await queryRunner.query(`ALTER TABLE \`clients\` CHANGE \`administrator_name\` \`administrator_name\` varchar(255) NULL`);

这些只是第二次迁移的一些行,实际上我所有表的列都是在第二次迁移中使用 ALTER TABLE CHANGE 脚本编写的,这很奇怪,因为我没有进行任何更改。即使在接下来的迁移中,这些脚本也会继续显示。

预期行为

我希望每次生成迁移时只显示对实体所做的更改,而不是每一列

包.json

"build": "tsc -p tsconfig.build.json",
"typeorm": "node -r ts-node/register ./node_modules/typeorm/cli.js -d src/ormconfig.ts",
"migration:revert": "npm run typeorm migration:revert",
"migration:run": "npm run build && npm run typeorm migration:run",
"migration:generate": "npm run build && npm run typeorm migration:generate",

ormconfig.ts

const ormconfiguration = {
type: getConnectionType(process.env.TYPEORM_CONNECTION),
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: [process.env.TYPEORM_ENTITIES],
migrations: [process.env.TYPEORM_MIGRATIONS],
},

.env

 #APP_CONFIG
 HOST=http://localhost:5000
 NODE_ENV=development
 #DATABASE
 TYPEORM_CONNECTION=mysql
 TYPEORM_HOST=db-dev
 TYPEORM_USERNAME=root
 TYPEORM_PASSWORD=admin321
 TYPEORM_DATABASE=suitcase_db
 TYPEORM_PORT=3306
 TYPEORM_SYNCHRONIZE=false
 TYPEORM_LOGGING=false
 # TYPEORM_ENTITIES= ./src/entities/*.entity.ts
 # TYPEORM_MIGRATIONS= ./src/migrations/*.ts

 # for working with npm run start:dev
 TYPEORM_ENTITIES=./dist/**/entities/*.entity.js
 TYPEORM_MIGRATIONS=./dist/**/migrations/*.js

 TYPEORM_ENTITIES_DIR= ./src/entities/
 TYPEORM_MIGRATIONS_DIR= ./src/migrations/
 TYPEORM_MIGRATIONS_RUN=false
 TYPEORM_DROP_SCHEMA=false

我的环境

Dependency  Version
Operating System    Ubuntu 20.04
Node.js version 16.13
Typescript version  4.5.2
TypeORM version 0.3.9

【问题讨论】:

  • 我在几乎相同的设置下遇到了完全相同的问题; CLI v0.3.11。生成迁移会创建一个巨大的更改文件,即使没有任何更改,就像它无法再正确检测到已经存在的内容一样。

标签: javascript mysql node.js ubuntu typeorm


【解决方案1】:

弄明白了。不幸的是,CLI >= 0.3.x 中非常丑陋的重大变化,但我坚信它仍然是最好的 ORM。在从 0.2.x 更新到 0.3.11 后,这是我必须做的,以阻止它产生大量无意义的迁移。

注意:这假设你是当前能够生成迁移但是尽管没有实体更改,但它在运行时会生成一堆无意义的更新。

  1. 完全备份您的本地数据库。完全导出数据/结构。如果事情发生意外以重新开始,这就是您将使用的方法。

  2. 出口只是数据从您的数据库到一个单独的文件。稍后我们将使用它来将您的数据库恢复到当前状态。

  3. 彻底擦除您的本地数据库——所有表格、所有数据。空数据库。

  4. 从你的/migrations文件夹复制任何一次迁移已经在其他环境中运行到安全的地方。稍后我们将使用它来将所有迁移压缩到该文件中,因为我们是保证它已经运行在其他环境中。只需选择一个您确定存在于任何/所有环境中的 migrations 表中的一个。当我们部署时它会被跳过,并允许我们将自己重置为仅 1 次迁移,坦率地说,无论如何都需要时不时地完成。

  5. 完全清空所有迁移的 /migrations 文件夹。

  6. 清理你的/dist文件夹-rm -rf ./dist

    重要的:我发现针对已编译的实体运行是最安全的,因此如果您正在处理迁移,那么清除它很重要,因为如果不清除任何旧的实体,它们将留在 dist 文件夹中。

    1. 生成您的基准架构迁移。我使用的命令在 package.json 中配置如下,并使用 npm run migration:generate 调用:
      "prebuild": "rm -rf ./dist",
      "build": "nest build api",
      "typeorm": "typeorm-ts-node-commonjs -d ormconfig.ts",
      "migration:generate": "npm run build && npm run typeorm migration:generate -- ./migrations/schema"
    
    

    这输出到 ./migrations/1673535486257-schema.ts(作为示例文件名)并且应该包含完整的迁移以创建整个数据库。

    1. 启动您的 NestJs 服务器(在配置中使用 runMigrations: true)并让它完全启动。此时您的数据库应该是新鲜的,包含您本地实体的完整模式,但当然除了 1 个迁移条目外完全是空的。

    2. 使用您用于 SQL 导入的任何工具,尝试导入仅数据导出从早些时候。这应该在您的迁移表中导入时只有一个错误,可以忽略。如果导入一切顺利,那么现在您的数据库已完全恢复到之前的状态。

    3. 重要的一步!- 压缩你的迁移。不要因为您的迁移再次工作而感到高兴而跳过这个!您需要返回并参考我们隐藏的旧迁移文件并做几件事:

      1. 在您的/migrations 文件夹中更改新的(也是唯一的)迁移的文件名,以与您隐藏的文件的名称完全匹配。
      2. 在迁移文件本身中,更改它生成的迁移类的文字类名,使其与旧文件中的类名完全匹配。您还需要更改 name 属性直接在类名下面与旧文件相同。例如。:
      export class schema1673535486257 implements MigrationInterface {
          name = 'schema1673535486257'
          public async up(queryRunner: QueryRunner): Promise<void> { ... }
          public async down(queryRunner: QueryRunner): Promise<void> { ... }
      }
      

      这样做可以确保您的一次大迁移被最新的环境跳过。

      现在,下次您对实体进行更改并运行 npm run migration:generate 时,这将是您期望的差异迁移!

【讨论】:

    猜你喜欢
    • 2022-11-21
    • 2020-07-05
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 2021-10-17
    • 2021-12-21
    • 2016-12-29
    • 1970-01-01
    相关资源
    最近更新 更多