TypeORM生成迁移文件携带数据库名导致无法跨环境同步问题咨询
解决TypeORM迁移文件硬编码数据库名问题
方法一:动态替换现有迁移文件中的硬编码库名
我们可以直接从TypeORM提供的QueryRunner实例中获取当前连接配置的数据库名,替换所有硬编码的库名部分:
- 若关联的
startups表和当前表属于同一个库,直接移除库名前缀即可 - 若
startups属于独立的跨库,可通过环境变量读取对应环境的库名
修改后的迁移代码示例:
import { MigrationInterface, QueryRunner } from "typeorm"; export class PostRefactoring1632822259113 implements MigrationInterface { name = 'PostRefactoring1632822259113' public async up(queryRunner: QueryRunner): Promise<void> { // 动态获取当前连接的数据库名 const currentDb = queryRunner.connection.options.database as string; // 跨库场景下通过环境变量获取关联库名,不同环境配置对应变量即可 const startupDb = process.env.STARTUP_DB_NAME as string; await queryRunner.query(`CREATE TABLE \`${currentDb}\`.\`loan_process_trackers\` (\`id\` char(36) NOT NULL, \`fund_type\` enum ('BRIDGE_LOAN', 'VENTURE_DEBT') NOT NULL DEFAULT 'BRIDGE_LOAN', \`next_process_stage\` enum ('REQUEST_RAISED', 'DOCUMENTS_SUBMITTED', 'DOCUMENTS_VERIFIED', 'LOAN_APPROVED', 'LOAN_PROCESSED') NOT NULL, \`documents_request_raised\` tinyint NOT NULL DEFAULT 0, \`documents_submitted\` tinyint NOT NULL DEFAULT 0, \`documents_verified\` tinyint NOT NULL DEFAULT 0, \`loan_approved\` tinyint NOT NULL DEFAULT 0, \`loan_processed\` tinyint NOT NULL DEFAULT 0, \`created_at\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), \`updated_at\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`startup_id\` char(36) NULL, UNIQUE INDEX \`REL_33d6136fd8b0eb52e6f82d5f39\` (\`startup_id\`), PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); await queryRunner.query(`ALTER TABLE \`${currentDb}\`.\`loan_process_trackers\` ADD CONSTRAINT \`FK_33d6136fd8b0eb52e6f82d5f399\` FOREIGN KEY (\`startup_id\`) REFERENCES \`${startupDb}\`.\`startups\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); } public async down(queryRunner: QueryRunner): Promise<void> { const currentDb = queryRunner.connection.options.database as string; await queryRunner.query(`ALTER TABLE \`${currentDb}\`.\`loan_process_trackers\` DROP FOREIGN KEY \`FK_33d6136fd8b0eb52e6f82d5f399\``); await queryRunner.query(`DROP INDEX \`REL_33d6136fd8b0eb52e6f82d5f39\` ON \`${currentDb}\`.\`loan_process_trackers\``); await queryRunner.query(`DROP TABLE \`${currentDb}\`.\`loan_process_trackers\``); } }
如果不需要显式指定库名,也可以直接删除所有\dev_dbname`.`前缀,TypeORM会默认使用当前连接配置的数据库执行SQL。
方法二:从根源避免后续生成迁移自动带库名
生成迁移时自动带上硬编码库名,一般是实体配置或数据源配置有误导致的,做以下修改即可:
- 检查所有实体的
@Entity装饰器配置,移除其中写死的database属性 - 检查DataSource配置,不要在表名、迁移表名等配置项中硬编码库名
- 多库场景下,跨库关联的实体通过环境变量注入库名,不要写死固定值
内容的提问来源于stack exchange,提问作者Deepak
相关产品推荐
相关产品推荐

