-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
Description
Issue description
With SQLite3 driver when a batch of migrations is being run the Foreign Key management isn't put on hold during the migration. As a consequence it can trigger data loss if an alter on a table is done while this table is refered with a foreign key with DELETE ON CASCADE
Expected Behavior
When a I do a set of migrations which contains a addColum on a table referred to by another table foreign key which is set with ON DELETE CASCADE, I expect the migrations to be run without any loss of data contains in the tables.
Issue #2576 did solve it issue for an unitary migration but it does not applies with a set of pending migrations executed in batch mode.
Actual Behavior
Basically the issue is that each migration isn't framed by a PRAGMA goreign_key OFF/ON in dedicated transaction.
so a addColumn will generate batch that will recreate the table with the new column, transfering the data from old table to new one and then dropping the old table with finally the new table being renamed.
The table drop is triggering if any existing on delete CASCADE the delation of all the records tied to this table via foreign key.
the 2 recently added methods beforeMigration and afterMigration are not being called before and after the execution of each pending migration as shown in bellow code:
typeorm/src/migration/MigrationExecutor.ts
Lines 334 to 361 in c669f50
| await migration | |
| .instance!.up(queryRunner) | |
| .catch((error) => { | |
| // informative log about migration failure | |
| this.connection.logger.logMigration( | |
| `Migration "${migration.name}" failed, error: ${error?.message}`, | |
| ) | |
| throw error | |
| }) | |
| .then(async () => { | |
| // now when migration is executed we need to insert record about it into the database | |
| await this.insertExecutedMigration( | |
| queryRunner, | |
| migration, | |
| ) | |
| // commit transaction if we started it | |
| if (migration.transaction && transactionStartedByUs) | |
| await queryRunner.commitTransaction() | |
| }) | |
| .then(() => { | |
| // informative log about migration success | |
| successMigrations.push(migration) | |
| this.connection.logger.logSchemaBuild( | |
| `Migration ${migration.name} has been ${ | |
| this.fake ? "(fake)" : "" | |
| } executed successfully.`, | |
| ) | |
| }) |
Steps to reproduce
running this snippet you should reproduce the issue: https://github.com/sinopsysHK/typeorm-testcase
npm install
npm start
My Environment
| Dependency | Version |
|---|---|
| Operating System | Ubuntu 18.04.3 |
| Node.js version | 16.19.0 |
| Typescript version | 8.19.3 |
| TypeORM version | 0.3.11 |
Additional Context
No response
Relevant Database Driver(s)
- aurora-mysql
- aurora-postgres
- better-sqlite3
- cockroachdb
- cordova
- expo
- mongodb
- mysql
- nativescript
- oracle
- postgres
- react-native
- sap
- spanner
- sqlite
- sqlite-abstract
- sqljs
- sqlserver
Are you willing to resolve this issue by submitting a Pull Request?
Yes, I have the time, and I know how to start.