-
Notifications
You must be signed in to change notification settings - Fork 16.4k
Fix downgrade migrations failures #54508
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
airflow-core/src/airflow/migrations/versions/0082_3_1_0_make_bundle_name_not_nullable.py
Show resolved
Hide resolved
|
@ashb, test failure, looks unrelated |
|
@vatsrahul1001 It does look unrelated, but it's persistent across retries so I'm loathe to merge this unless something else is also exhibiting this failure |
|
Ah main build too -- okay we can merge. |
Backport failed to create: v3-0-test. View the failure log Run details
You can attempt to backport this manually by running: cherry_picker bc18493 v3-0-testThis should apply the commit to the v3-0-test branch and leave the commit in conflict state marking After you have resolved the conflicts, you can continue the backport process by running: cherry_picker --continue |
Fixes critical blocking issues when downgrading Airflow from 3.x to 2.x across PostgreSQL, MySQL, and SQLite databases. These issues were discovered after [PR #54399](#54399) unblocked the downgrade process. **Error:** ``` sqlalchemy.exc.IntegrityError: (psycopg2.errors.NotNullViolation) column "try_number" of relation "task_reschedule" contains null values ``` **Root Cause:** Migration [`0068_3_0_0_ti_table_id_unique_per_try.py:L99`](https://github.com/apache/airflow/blob/main/airflow-core/src/airflow/migrations/versions/0068_3_0_0_ti_table_id_unique_per_try.py#L99) uses `default="1"` instead of `server_default="1"`, causing existing NULL values to remain NULL when the column is made NOT NULL. **Solution:** Replace `default="1"` with `server_default="1"` to ensure database-level default value assignment. **Error:** ``` sqlalchemy.exc.IntegrityError: (psycopg2.errors.NotNullViolation) column "task_instance_id" of relation "task_instance_history" contains null values ``` **Root Cause:** The `task_instance_id` column is made NOT NULL during downgrade but contains NULL values, even though this column gets dropped entirely in the same migration. **Solution:** Make `task_instance_id` column nullable since it's immediately dropped and not needed in 2.x schema. **Error:** ``` sqlalchemy.exc.OperationalError: (MySQLdb.OperationalError) (1138, 'Invalid use of NULL value') ``` **Root Cause:** MySQL query attempts to JOIN on NULL `id` values in `task_instance_history`: ```sql UPDATE task_instance_history tih JOIN ( SELECT id, ROW_NUMBER() OVER (ORDER BY id) AS row_num FROM task_instance_history ) AS temp ON tih.id = temp.id SET tih.id = temp.row_num; ``` The `id` column was just re-added as nullable with all NULL values, making the JOIN fail. **Solution:** Replace with MySQL variable-based sequential numbering: ```sql SET @row_number = 0; UPDATE task_instance_history SET id = (@row_number := @row_number + 1) ORDER BY try_id; ``` **Error:** ``` sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) FOREIGN KEY constraint failed ``` **Root Cause:** SQLite's strict foreign key checking prevents dropping the `dag` table during `batch_alter_table` operations when other tables reference it. **Solution:** Add SQLite-specific handling to temporarily disable foreign key constraints: ```python if dialect_name == "sqlite": conn.execute(text("PRAGMA foreign_keys=OFF")) try: # batch operations finally: conn.execute(text("PRAGMA foreign_keys=ON")) ``` Verified successful downgrade from Airflow 3.0.5rc1 to 2.11 on: - [x] PostgreSQL - [x] MySQL - [x] SQLite (cherry picked from commit bc18493)
Hey @vatsrahul1001 Can you explain this in more detail. I did not get why this column is not needed in 2.x |
Fixes critical blocking issues when downgrading Airflow from 3.x to 2.x across PostgreSQL, MySQL, and SQLite databases. These issues were discovered after PR #54399 unblocked the downgrade process.
1. PostgreSQL - NOT NULL Violation in
task_rescheduleTableError:
Root Cause: Migration
0068_3_0_0_ti_table_id_unique_per_try.py:L99usesdefault="1"instead ofserver_default="1", causing existing NULL values to remain NULL when the column is made NOT NULL.Solution: Replace
default="1"withserver_default="1"to ensure database-level default value assignment.2. PostgreSQL - NOT NULL Violation in
task_instance_historyTableError:
Root Cause: The
task_instance_idcolumn is made NOT NULL during downgrade but contains NULL values, even though this column gets dropped entirely in the same migration.Solution: Make
task_instance_idcolumn nullable since it's immediately dropped and not needed in 2.x schema.3. MySQL - Invalid NULL Value During Row Numbering
Error:
Root Cause: MySQL query attempts to JOIN on NULL
idvalues intask_instance_history:The
idcolumn was just re-added as nullable with all NULL values, making the JOIN fail.Solution: Replace with MySQL variable-based sequential numbering:
4. SQLite - Foreign Key Constraint During Batch Operations
Error:
Root Cause: SQLite's strict foreign key checking prevents dropping the
dagtable duringbatch_alter_tableoperations when other tables reference it.Solution: Add SQLite-specific handling to temporarily disable foreign key constraints:
Testing
Verified successful downgrade from Airflow 3.0.5rc1 to 2.11 on: