fix(migrations): move UPDATEs inside disable_sqlite_fkeys in migration 0097#64876
fix(migrations): move UPDATEs inside disable_sqlite_fkeys in migration 0097#64876Lee-W merged 1 commit intoapache:mainfrom
Conversation
|
@vatsrahul1001 It looks like we used the wrong approach for testing, and I applied the wrong constraint during RC1 testing. I didn't have time to test it on RC2 until it was released yesterday 🤦♂️ After running the following command we discussed, I found out there's no dag_run in the DB. breeze start-airflow --backend sqlite --load-example-dags --use-airflow-version 3.1.8
breeze start-airflow --backend sqlite --load-example-dagsSo here's what I do for verifying this PR is correct (how to reproduce was detailed in the description) VariablesOLD_VERSION=3.1.8
NEW_VERSION=3.2.0 # or a specific SHA-1Step 1: Start Airflow $OLD_VERSIONbreeze start-airflow \
--backend sqlite \
--load-example-dags \
--use-airflow-version $OLD_VERSION Step 2: Populate the databaseRun a few Dags manually to create rows in Dag run, task instance, and other tables that reference Dags via foreign keys. Step 3: Save the database and exit Breezecp /root/airflow/sqlite/airflow.db /files/airflow_$OLD_VERSION.dbExit Breeze with Step 4: Checkout the target version and start Breezegit checkout $NEW_VERSION
breeze shell \
--backend sqlite \
--mount-sources selectedStep 5: Restore the saved databasecp /files/airflow_$OLD_VERSION.db /root/airflow/sqlite/airflow.dbStep 6: Run the migration and testairflow db migrate
airflow db downgrade --to-revision 937cbd173ca1 -y
airflow db migrate |
Dev-iL
left a comment
There was a problem hiding this comment.
Can we modify the migration test (or add a new regression test) to capture this sort of issues?
jason810496
left a comment
There was a problem hiding this comment.
Can we modify the migration test (or add a new regression test) to capture this sort of issues?
Perhpas we need to raise Dev List about adding unit test or any better testing approach to harden the whole DB migration. I had discussed with Wei and other folks before, but we haven't settled down the concore approach.
I can try to find time to do it in another PR, but I think this is needed for users who use SQLite as a backend to upgrade to 3.2.x.
I'm not sure whether we should bring it up on the dev list without at least some idea of what it is. But if anyone already has an idea to do it correctly, they're more than welcome to take action. 🙂 |
|
I'm going to merge it and backport it. will create another issue for the testing thing |
|
Hi maintainer, this PR was merged without a milestone set.
|
Backport successfully created: v3-2-testNote: As of Merging PRs targeted for Airflow 3.X In matter of doubt please ask in #release-management Slack channel.
|
…tests Prevent migration bugs like apache#64876 (DML before disable_sqlite_fkeys silently breaking SQLite PRAGMA) from reaching production by adding: 1. AST-based static analysis tests (test_migration_patterns.py) that detect three anti-patterns across all migration files: - MIG001: DML before disable_sqlite_fkeys (triggers autobegin) - MIG002: DDL before disable_sqlite_fkeys (triggers autobegin) - MIG003: DML without context.is_offline_mode() guard 2. Unit tests for migration utility functions (test_migration_utils.py) covering disable_sqlite_fkeys, mysql_drop_foreignkey_if_exists, and ignore_sqlite_value_error with real database backends. 3. Fixes confirmed SQLite PRAGMA bugs in migrations 0100 and 0106 by moving all operations inside the disable_sqlite_fkeys block. 4. Adds # noqa: MIG0XX suppression comments (with reasons) to 20 old migrations with acknowledged violations, and configures ruff to preserve them via external = ["MIG"].
…tests Prevent migration bugs like apache#64876 (DML before disable_sqlite_fkeys silently breaking SQLite PRAGMA) from reaching production by adding: 1. AST-based static analysis tests (test_migration_patterns.py) that detect three anti-patterns across all migration files: - MIG001: DML before disable_sqlite_fkeys (triggers autobegin) - MIG002: DDL before disable_sqlite_fkeys (triggers autobegin) - MIG003: DML without context.is_offline_mode() guard 2. Unit tests for migration utility functions (test_migration_utils.py) covering disable_sqlite_fkeys, mysql_drop_foreignkey_if_exists, and ignore_sqlite_value_error with real database backends. 3. Fixes confirmed SQLite PRAGMA bugs in migrations 0100 and 0106 by moving all operations inside the disable_sqlite_fkeys block. 4. Adds # noqa: MIG0XX suppression comments (with reasons) to 20 old migrations with acknowledged violations, and configures ruff to preserve them via external = ["MIG"].
Prevent migration bugs like apache#64876 (DML before disable_sqlite_fkeys silently breaking SQLite PRAGMA) from reaching production by adding: 1. AST-based static analysis tests (test_migration_patterns.py) that detect three anti-patterns across all migration files: - MIG001: DML before disable_sqlite_fkeys (triggers autobegin) - MIG002: DDL before disable_sqlite_fkeys (triggers autobegin) - MIG003: DML without context.is_offline_mode() guard 2. Unit tests for migration utility functions (test_migration_utils.py) covering disable_sqlite_fkeys, mysql_drop_foreignkey_if_exists, and ignore_sqlite_value_error with real database backends. 3. Fixes confirmed SQLite PRAGMA bugs in migrations 0100 and 0106 by moving all operations inside the disable_sqlite_fkeys block. 4. Adds # noqa: MIG0XX suppression comments (with reasons) to 20 old migrations with acknowledged violations, and configures ruff to preserve them via external = ["MIG"].
Prevent migration bugs like apache#64876 (DML before disable_sqlite_fkeys silently breaking SQLite PRAGMA) from reaching production by adding: 1. AST-based static analysis tests (test_migration_patterns.py) that detect three anti-patterns across all migration files: - MIG001: DML before disable_sqlite_fkeys (triggers autobegin) - MIG002: DDL before disable_sqlite_fkeys (triggers autobegin) - MIG003: DML without context.is_offline_mode() guard 2. Unit tests for migration utility functions (test_migration_utils.py) covering disable_sqlite_fkeys, mysql_drop_foreignkey_if_exists, and ignore_sqlite_value_error with real database backends. 3. Fixes confirmed SQLite PRAGMA bugs in migrations 0100 and 0106 by moving all operations inside the disable_sqlite_fkeys block. 4. Adds # noqa: MIG0XX suppression comments (with reasons) to 20 old migrations with acknowledged violations, and configures ruff to preserve them via external = ["MIG"].
Prevent migration bugs like apache#64876 (DML before disable_sqlite_fkeys silently breaking SQLite PRAGMA) from reaching production by adding: 1. AST-based static analysis tests (test_migration_patterns.py) that detect three anti-patterns across all migration files: - MIG001: DML before disable_sqlite_fkeys (triggers autobegin) - MIG002: DDL before disable_sqlite_fkeys (triggers autobegin) - MIG003: DML without context.is_offline_mode() guard 2. Unit tests for migration utility functions (test_migration_utils.py) covering disable_sqlite_fkeys, mysql_drop_foreignkey_if_exists, and ignore_sqlite_value_error with real database backends. 3. Fixes confirmed SQLite PRAGMA bugs in migrations 0100 and 0106 by moving all operations inside the disable_sqlite_fkeys block. 4. Adds # noqa: MIG0XX suppression comments (with reasons) to 20 old migrations with acknowledged violations, and configures ruff to preserve them via external = ["MIG"].
Why
Migration 0097 failed on SQLite with FOREIGN KEY constraint failed when running DROP TABLE dag. PRAGMA foreign_keys=off (issued inside disable_sqlite_fkeys) is silently ignored when a transaction is already active — SQLite limitation. The two UPDATE statements before disable_sqlite_fkeys triggered SQLAlchemy's autobegin, starting a transaction before the PRAGMA ran.
How to reproduce
Run a few Dags randomly. We need rows in the Dag run and task instance (or whatever rows that references Dag using FK)
Go to the
Shelltab in the breeze terminalRun
What
Move the UPDATE statements inside disable_sqlite_fkeys so PRAGMA foreign_keys=off executes before autobegin opens a transaction.
Was generative AI tooling used to co-author this PR?
Generated-by: [Claude] following the guidelines
{pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.