You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[x] latest
[ ] @next
[ ] 0.x.x (or put your version here)
I'd like to use MigrationExecutor to deal with migrations myself, today all that can be done is calling runMigrations, and a few other methods.
In my scenario, if by some reason a duplicated table/column error is thrown I'd like to ignore this migration, add it to done migrations and call the next one, this is impossible without calling MigrationExecutor private API or reimplementing it.
This is a piece of code that show how I'm doing it today:
import{Connection,QueryRunner}from'typeorm/browser'import{MigrationExecutor}from'typeorm/browser/migration/MigrationExecutor'import_from'lodash'constIGNORED_ERRORS=[/table .+ already exists/i,/index .+ already exists/i,/duplicate column name/i,/no such table: .+/i,/no such index: .+/i,].map(r=>newRegExp(r))exportclassDatabaseMigrationService{executor: anyqueryRunner: QueryRunnerconstructor(connection: Connection){this.executor=newMigrationExecutor(connection)this.queryRunner=this.executor.queryRunner||connection.createQueryRunner('master')}call(){constqueryRunner=this.queryRunnerreturnnewPromise(async(resolve,reject)=>{try{constmigrations: Migration[]=this.executor.getMigrations()constdoneMigrations=awaitthis.executor.loadExecutedMigrations(queryRunner)constnewMigrations: any=_.reject(migrations,migration=>_.find(doneMigrations,['timestamp',migration.timestamp]))_.each(newMigrations,asyncmigration=>awaitthis.executeMigration(queryRunner,migration))resolve()}catch(e){reject(e)}finally{if(this.queryRunner){this.queryRunner.release()}}})}executeMigration(queryRunner: QueryRunner,migration: Migration): Promise<boolean>{this.executor.transaction=falsereturnnewPromise(async(resolve,reject)=>{try{this.registerLog(`Migration ${migration.name} started`)await(migration.instanceasany).up(queryRunner)awaitthis.insertExecutedMigration(migration)resolve(true)}catch(e){this.registerLog(e.message,{level: 'ERROR'})if(this.shouldIgnoreError(e)){this.insertExecutedMigration(migration)resolve(true)}else{reject(e)}}finally{this.registerLog(`Migration ${migration.name} finished`)}})}shouldIgnoreError(error: Error): boolean{return_.some(IGNORED_ERRORS,r=>r.test(error.message))}registerLog(content: string,props={}){// register this with external apis ...}insertExecutedMigration(migration: Migration){returnthis.executor.insertExecutedMigration(this.queryRunner,migration)}}
I'd like to propose this changes:
Make getMigrations, loadExecutedMigrations, insertExecutedMigration, deleteExecutedMigration, methods public
Make import { MigrationExecutor } from 'typeorm' available
Maybe add/rename some methods (ie.: showMigrations could be hasMigrationsPending, while showMigrations could be preserved as a way to log migration status), add getPendingMigrations, rename/add loadExecutedMigrations to getDoneMigrations, and maybe other methods
If this is approved I could put a work on it.
The text was updated successfully, but these errors were encountered:
Issue type:
[ ] question
[ ] bug report
[x] feature request
[ ] documentation issue
Database system/driver:
Doesn't apply to a specific driver.
TypeORM version:
[x]
latest
[ ]
@next
[ ]
0.x.x
(or put your version here)I'd like to use MigrationExecutor to deal with migrations myself, today all that can be done is calling
runMigrations
, and a few other methods.In my scenario, if by some reason a duplicated table/column error is thrown I'd like to ignore this migration, add it to done migrations and call the next one, this is impossible without calling MigrationExecutor private API or reimplementing it.
This is a piece of code that show how I'm doing it today:
I'd like to propose this changes:
import { MigrationExecutor } from 'typeorm'
availableIf this is approved I could put a work on it.
The text was updated successfully, but these errors were encountered: