Skip to content

[sqlite3] migrations batch do not halt foreign key management #9770

@sinopsysHK

Description

@sinopsysHK

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:

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions