Skip to content

fix(migrations): move UPDATEs inside disable_sqlite_fkeys in migration 0097#64876

Merged
Lee-W merged 1 commit intoapache:mainfrom
astronomer:fix-migration
Apr 9, 2026
Merged

fix(migrations): move UPDATEs inside disable_sqlite_fkeys in migration 0097#64876
Lee-W merged 1 commit intoapache:mainfrom
astronomer:fix-migration

Conversation

@Lee-W
Copy link
Copy Markdown
Member

@Lee-W Lee-W commented Apr 8, 2026

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

  1. Bring up a 3.1.8 instance
breeze start-airflow  --backend sqlite --load-example-dags --use-airflow-version 3.1.8
  1. Run a few Dags randomly. We need rows in the Dag run and task instance (or whatever rows that references Dag using FK)

  2. Go to the Shell tab in the breeze terminal

  3. Run

uv pip install apache-airflow==3.2.0
uv run airflow db migrate

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?
  • Yes (please specify the tool below)

Generated-by: [Claude] following the guidelines


  • Read the Pull Request Guidelines for more information. Note: commit author/co-author name and email in commits become permanently public when merged.
  • For fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
  • When adding dependency, check compliance with the ASF 3rd Party License Policy.
  • For significant user-facing changes create newsfragment: {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.

@Lee-W Lee-W requested a review from ephraimbuddy as a code owner April 8, 2026 02:40
@boring-cyborg boring-cyborg bot added the area:db-migrations PRs with DB migration label Apr 8, 2026
@Lee-W Lee-W requested a review from vatsrahul1001 April 8, 2026 03:28
@Lee-W
Copy link
Copy Markdown
Member Author

Lee-W commented Apr 8, 2026

@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-dags

So here's what I do for verifying this PR is correct (how to reproduce was detailed in the description)

Variables

OLD_VERSION=3.1.8
NEW_VERSION=3.2.0  # or a specific SHA-1

Step 1: Start Airflow $OLD_VERSION

breeze start-airflow \
    --backend sqlite \
    --load-example-dags \
    --use-airflow-version $OLD_VERSION 

Step 2: Populate the database

Run 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 Breeze

cp /root/airflow/sqlite/airflow.db /files/airflow_$OLD_VERSION.db

Exit Breeze with stop_airflow.

Step 4: Checkout the target version and start Breeze

git checkout $NEW_VERSION
breeze shell \
    --backend sqlite \
    --mount-sources selected

Step 5: Restore the saved database

cp /files/airflow_$OLD_VERSION.db /root/airflow/sqlite/airflow.db

Step 6: Run the migration and test

airflow db migrate
airflow db downgrade --to-revision 937cbd173ca1 -y
airflow db migrate

@Lee-W Lee-W added the backport-to-v3-2-test Mark PR with this label to backport to v3-2-test branch label Apr 8, 2026
Copy link
Copy Markdown
Collaborator

@Dev-iL Dev-iL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we modify the migration test (or add a new regression test) to capture this sort of issues?

Copy link
Copy Markdown
Member

@jason810496 jason810496 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@Lee-W
Copy link
Copy Markdown
Member Author

Lee-W commented Apr 9, 2026

Can we modify the migration test (or add a new regression test) to capture this sort of issues?

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.

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'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. 🙂

@Lee-W
Copy link
Copy Markdown
Member Author

Lee-W commented Apr 9, 2026

I'm going to merge it and backport it. will create another issue for the testing thing

@Lee-W Lee-W merged commit 666879c into apache:main Apr 9, 2026
82 checks passed
@Lee-W Lee-W deleted the fix-migration branch April 9, 2026 03:24
@github-actions github-actions bot added this to the Airflow 3.2.1 milestone Apr 9, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 9, 2026

Hi maintainer, this PR was merged without a milestone set.
We've automatically set the milestone to Airflow 3.2.1 based on: backport label targeting v3-2-test
If this milestone is not correct, please update it to the appropriate milestone.

This comment was generated by Milestone Tag Assistant.

github-actions bot pushed a commit that referenced this pull request Apr 9, 2026
… in migration 0097 (#64876)

(cherry picked from commit 666879c)

Co-authored-by: Wei Lee <weilee.rx@gmail.com>
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 9, 2026

Backport successfully created: v3-2-test

Note: As of Merging PRs targeted for Airflow 3.X
the committer who merges the PR is responsible for backporting the PRs that are bug fixes (generally speaking) to the maintenance branches.

In matter of doubt please ask in #release-management Slack channel.

Status Branch Result
v3-2-test PR Link

potiuk pushed a commit that referenced this pull request Apr 9, 2026
… in migration 0097 (#64876) (#64940)

(cherry picked from commit 666879c)

Co-authored-by: Wei Lee <weilee.rx@gmail.com>
Dev-iL added a commit to Dev-iL/airflow that referenced this pull request Apr 9, 2026
…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"].
Dev-iL added a commit to Dev-iL/airflow that referenced this pull request Apr 9, 2026
…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"].
Dev-iL added a commit to Dev-iL/airflow that referenced this pull request Apr 9, 2026
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"].
Dev-iL added a commit to Dev-iL/airflow that referenced this pull request Apr 9, 2026
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"].
Dev-iL added a commit to Dev-iL/airflow that referenced this pull request Apr 10, 2026
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"].
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:db-migrations PRs with DB migration backport-to-v3-2-test Mark PR with this label to backport to v3-2-test branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants