This is an automated email from the ASF dual-hosted git repository. kaxilnaik pushed a commit to branch v3-0-test in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/v3-0-test by this push: new 909d424ef9c [v3-0-test] Raise exception if downgrade can't proceed due to no `ab_user` table (#50343) (#50351) 909d424ef9c is described below commit 909d424ef9c5963c3b7fbffd85e48f8765ce61d6 Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> AuthorDate: Tue May 13 01:02:08 2025 +0530 [v3-0-test] Raise exception if downgrade can't proceed due to no `ab_user` table (#50343) (#50351) * Raise exception if downgrade can't proceed due to no `ab_user` table We only log the error that the downgrade can't proceed if the `ab_user` table is not found, but we should raise an exception instead. Currently, the CI migrations don't exit on error, which prevents the necessary tests from running. Also updated the CI migration tests to export DB manager at the shell because it seems that's not happening, hence why downgrade is running correctly. * result can be none so check before accessing row_count * dont raise in unittest mode (cherry picked from commit 0f0fc02d60bf68b7a1b61095cfa4aab75cb2ae71) Co-authored-by: Ephraim Anierobi <splendidzig...@gmail.com> --- .github/actions/migration_tests/action.yml | 21 ++-- airflow-core/docs/img/airflow_erd.sha256 | 2 +- airflow-core/docs/img/airflow_erd.svg | 108 ++++++++++----------- ...3_0_0_add_uuid_primary_key_to_task_instance_.py | 4 +- airflow-core/src/airflow/utils/db.py | 10 +- airflow-core/tests/unit/utils/test_db.py | 13 ++- 6 files changed, 84 insertions(+), 74 deletions(-) diff --git a/.github/actions/migration_tests/action.yml b/.github/actions/migration_tests/action.yml index ed71e21407d..933c9a847a1 100644 --- a/.github/actions/migration_tests/action.yml +++ b/.github/actions/migration_tests/action.yml @@ -25,11 +25,12 @@ runs: shell: bash run: | breeze shell "${{ env.AIRFLOW_2_CMD }}" --use-airflow-version 2.10.5 --answer y && - breeze shell "${{ env.AIRFLOW_3_CMD }}" --no-db-cleanup + breeze shell "export AIRFLOW__DATABASE__EXTERNAL_DB_MANAGERS=${{env.DB_MANGERS}} + ${{ env.AIRFLOW_3_CMD }}" --no-db-cleanup env: COMPOSE_PROJECT_NAME: "docker-compose" - AIRFLOW__DATABASE__EXTERNAL_DB_MANAGERS: "airflow.providers.fab.auth_manager.models.db.FABDBManager" DB_RESET: "false" + DB_MANAGERS: "airflow.providers.fab.auth_manager.models.db.FABDBManager" AIRFLOW_2_CMD: >- airflow db reset --skip-init -y && airflow db migrate --to-revision heads @@ -47,11 +48,12 @@ runs: shell: bash run: > breeze shell "${{ env.AIRFLOW_2_CMD }}" --use-airflow-version 2.10.5 --answer y && - breeze shell "${{ env.AIRFLOW_3_CMD }}" --no-db-cleanup + breeze shell "export AIRFLOW__DATABASE__EXTERNAL_DB_MANAGERS=${{env.DB_MANGERS}} + ${{ env.AIRFLOW_3_CMD }}" --no-db-cleanup env: COMPOSE_PROJECT_NAME: "docker-compose" - AIRFLOW__DATABASE__EXTERNAL_DB_MANAGERS: "airflow.providers.fab.auth_manager.models.db.FABDBManager" DB_RESET: "false" + DB_MANAGERS: "airflow.providers.fab.auth_manager.models.db.FABDBManager" AIRFLOW_2_CMD: >- airflow db reset -y AIRFLOW_3_CMD: >- @@ -67,13 +69,14 @@ runs: - name: "Test ORM migration ${{env.BACKEND}}" shell: bash run: > - breeze shell "airflow db reset -y && + breeze shell "export AIRFLOW__DATABASE__EXTERNAL_DB_MANAGERS=${{env.DB_MANAGERS}} && + airflow db reset -y && airflow db migrate --to-revision heads && airflow db downgrade -n 2.7.0 -y && airflow db migrate" env: COMPOSE_PROJECT_NAME: "docker-compose" - AIRFLOW__DATABASE__EXTERNAL_DB_MANAGERS: "airflow.providers.fab.auth_manager.models.db.FABDBManager" + DB_MANAGERS: "airflow.providers.fab.auth_manager.models.db.FABDBManager" - name: "Bring compose down again" shell: bash run: breeze down @@ -82,12 +85,14 @@ runs: - name: "Test offline migration ${{env.BACKEND}}" shell: bash run: > - breeze shell "airflow db reset -y && + breeze shell + "export AIRFLOW__DATABASE__EXTERNAL_DB_MANAGERS=${{env.DB_MANAGERS}} && + airflow db reset -y && airflow db downgrade -n 2.7.0 -y && airflow db migrate -s" env: COMPOSE_PROJECT_NAME: "docker-compose" - AIRFLOW__DATABASE__EXTERNAL_DB_MANAGERS: "airflow.providers.fab.auth_manager.models.db.FABDBManager" + DB_MANAGERS: "airflow.providers.fab.auth_manager.models.db.FABDBManager" if: env.BACKEND != 'sqlite' - name: "Bring any containers left down" shell: bash diff --git a/airflow-core/docs/img/airflow_erd.sha256 b/airflow-core/docs/img/airflow_erd.sha256 index f92146f77a8..da3765115e3 100644 --- a/airflow-core/docs/img/airflow_erd.sha256 +++ b/airflow-core/docs/img/airflow_erd.sha256 @@ -1 +1 @@ -1b5221fa589cfc8652242b95f24d218c632168238933b82b533321a217c2447f \ No newline at end of file +066cb891884eea1ee0496b5c507d4a52c20d0440387f9ec8bacb1d616a26e40e \ No newline at end of file diff --git a/airflow-core/docs/img/airflow_erd.svg b/airflow-core/docs/img/airflow_erd.svg index 7ce02c7187b..879c9f17f90 100644 --- a/airflow-core/docs/img/airflow_erd.svg +++ b/airflow-core/docs/img/airflow_erd.svg @@ -1482,35 +1482,81 @@ <text text-anchor="start" x="302.2" y="-1915.3" font-family="Times,serif" font-size="14.00">{0,1}</text> </g> <!-- dag--dag_schedule_asset_alias_reference --> -<g id="edge18" class="edge"> +<g id="edge19" class="edge"> <title>dag--dag_schedule_asset_alias_reference</title> <path fill="none" stroke="#7f7f7f" stroke-dasharray="5,2" d="M717.95,-2244.65C753.67,-2362.49 793.89,-2497.38 829,-2620.5 863.21,-2740.45 820.19,-2797.34 902,-2891.5 904.68,-2894.59 907.51,-2897.55 910.46,-2900.4"/> <text text-anchor="start" x="879.46" y="-2889.2" font-family="Times,serif" font-size="14.00">0..N</text> <text text-anchor="start" x="707.95" y="-2248.45" font-family="Times,serif" font-size="14.00">1</text> </g> <!-- dag--dag_schedule_asset_reference --> -<g id="edge19" class="edge"> +<g id="edge20" class="edge"> <title>dag--dag_schedule_asset_reference</title> <path fill="none" stroke="#7f7f7f" stroke-dasharray="5,2" d="M802.43,-2244.52C832.55,-2282.49 865.87,-2318.39 902,-2348.5 911.97,-2356.81 922.95,-2364.36 934.43,-2371.21"/> <text text-anchor="start" x="903.43" y="-2360.01" font-family="Times,serif" font-size="14.00">0..N</text> <text text-anchor="start" x="792.43" y="-2248.32" font-family="Times,serif" font-size="14.00">1</text> </g> <!-- dag--task_outlet_asset_reference --> -<g id="edge20" class="edge"> +<g id="edge21" class="edge"> <title>dag--task_outlet_asset_reference</title> <path fill="none" stroke="#7f7f7f" stroke-dasharray="5,2" d="M730.32,-2244.59C773.32,-2336.19 829.95,-2430.88 902,-2503.5 913.84,-2515.43 927.58,-2526.05 942.1,-2535.44"/> <text text-anchor="start" x="911.1" y="-2524.24" font-family="Times,serif" font-size="14.00">0..N</text> <text text-anchor="start" x="720.32" y="-2248.39" font-family="Times,serif" font-size="14.00">1</text> </g> <!-- dag--asset_dag_run_queue --> -<g id="edge21" class="edge"> +<g id="edge22" class="edge"> <title>dag--asset_dag_run_queue</title> <path fill="none" stroke="#7f7f7f" stroke-dasharray="5,2" d="M829.14,-2164.26C852.52,-2184.43 876.97,-2203.28 902,-2219.5 908.43,-2223.67 915.16,-2227.61 922.08,-2231.33"/> <text text-anchor="start" x="891.08" y="-2220.13" font-family="Times,serif" font-size="14.00">0..N</text> <text text-anchor="start" x="829.14" y="-2153.06" font-family="Times,serif" font-size="14.00">1</text> </g> -<!-- dag_schedule_asset_name_reference --> +<!-- dag_version --> <g id="node25" class="node"> +<title>dag_version</title> +<polygon fill="none" stroke="black" points="943.5,-2178.5 943.5,-2206.5 1224.5,-2206.5 1224.5,-2178.5 943.5,-2178.5"/> +<text text-anchor="start" x="1029.5" y="-2189.7" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="16.00">dag_version</text> +<polygon fill="none" stroke="black" points="943.5,-2153.5 943.5,-2178.5 1224.5,-2178.5 1224.5,-2153.5 943.5,-2153.5"/> +<text text-anchor="start" x="948.5" y="-2163.3" font-family="Helvetica,sans-Serif" text-decoration="underline" font-size="14.00">id</text> +<text text-anchor="start" x="961.5" y="-2163.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> +<text text-anchor="start" x="966.5" y="-2163.3" font-family="Helvetica,sans-Serif" font-size="14.00"> [UUID]</text> +<text text-anchor="start" x="1018.5" y="-2163.3" font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text> +<polygon fill="none" stroke="black" points="943.5,-2128.5 943.5,-2153.5 1224.5,-2153.5 1224.5,-2128.5 943.5,-2128.5"/> +<text text-anchor="start" x="948.5" y="-2138.3" font-family="Helvetica,sans-Serif" font-size="14.00">bundle_name</text> +<text text-anchor="start" x="1042.5" y="-2138.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> +<text text-anchor="start" x="1047.5" y="-2138.3" font-family="Helvetica,sans-Serif" font-size="14.00"> [VARCHAR(250)]</text> +<polygon fill="none" stroke="black" points="943.5,-2103.5 943.5,-2128.5 1224.5,-2128.5 1224.5,-2103.5 943.5,-2103.5"/> +<text text-anchor="start" x="948.5" y="-2113.3" font-family="Helvetica,sans-Serif" font-size="14.00">bundle_version</text> +<text text-anchor="start" x="1054.5" y="-2113.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> +<text text-anchor="start" x="1059.5" y="-2113.3" font-family="Helvetica,sans-Serif" font-size="14.00"> [VARCHAR(250)]</text> +<polygon fill="none" stroke="black" points="943.5,-2078.5 943.5,-2103.5 1224.5,-2103.5 1224.5,-2078.5 943.5,-2078.5"/> +<text text-anchor="start" x="948.5" y="-2088.3" font-family="Helvetica,sans-Serif" font-size="14.00">created_at</text> +<text text-anchor="start" x="1021.5" y="-2088.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> +<text text-anchor="start" x="1026.5" y="-2088.3" font-family="Helvetica,sans-Serif" font-size="14.00"> [TIMESTAMP]</text> +<text text-anchor="start" x="1122.5" y="-2088.3" font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text> +<polygon fill="none" stroke="black" points="943.5,-2053.5 943.5,-2078.5 1224.5,-2078.5 1224.5,-2053.5 943.5,-2053.5"/> +<text text-anchor="start" x="948.5" y="-2063.3" font-family="Helvetica,sans-Serif" font-size="14.00">dag_id</text> +<text text-anchor="start" x="994.5" y="-2063.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> +<text text-anchor="start" x="999.5" y="-2063.3" font-family="Helvetica,sans-Serif" font-size="14.00"> [VARCHAR(250)]</text> +<text text-anchor="start" x="1120.5" y="-2063.3" font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text> +<polygon fill="none" stroke="black" points="943.5,-2028.5 943.5,-2053.5 1224.5,-2053.5 1224.5,-2028.5 943.5,-2028.5"/> +<text text-anchor="start" x="948.5" y="-2038.3" font-family="Helvetica,sans-Serif" font-size="14.00">last_updated</text> +<text text-anchor="start" x="1038.5" y="-2038.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> +<text text-anchor="start" x="1043.5" y="-2038.3" font-family="Helvetica,sans-Serif" font-size="14.00"> [TIMESTAMP]</text> +<text text-anchor="start" x="1139.5" y="-2038.3" font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text> +<polygon fill="none" stroke="black" points="943.5,-2003.5 943.5,-2028.5 1224.5,-2028.5 1224.5,-2003.5 943.5,-2003.5"/> +<text text-anchor="start" x="948.5" y="-2013.3" font-family="Helvetica,sans-Serif" font-size="14.00">version_number</text> +<text text-anchor="start" x="1061.5" y="-2013.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> +<text text-anchor="start" x="1066.5" y="-2013.3" font-family="Helvetica,sans-Serif" font-size="14.00"> [INTEGER]</text> +<text text-anchor="start" x="1143.5" y="-2013.3" font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text> +</g> +<!-- dag--dag_version --> +<g id="edge16" class="edge"> +<title>dag--dag_version</title> +<path fill="none" stroke="#7f7f7f" stroke-dasharray="5,2" d="M829.26,-2007.49C864.9,-2021.28 901.24,-2035.35 934.86,-2048.36"/> +<text text-anchor="start" x="903.86" y="-2037.16" font-family="Times,serif" font-size="14.00">0..N</text> +<text text-anchor="start" x="829.26" y="-1996.29" font-family="Times,serif" font-size="14.00">1</text> +</g> +<!-- dag_schedule_asset_name_reference --> +<g id="node26" class="node"> <title>dag_schedule_asset_name_reference</title> <polygon fill="none" stroke="black" points="914.5,-1393.5 914.5,-1421.5 1253.5,-1421.5 1253.5,-1393.5 914.5,-1393.5"/> <text text-anchor="start" x="919.5" y="-1404.7" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="16.00">dag_schedule_asset_name_reference</text> @@ -1531,14 +1577,14 @@ <text text-anchor="start" x="1093.5" y="-1328.3" font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text> </g> <!-- dag--dag_schedule_asset_name_reference --> -<g id="edge16" class="edge"> +<g id="edge17" class="edge"> <title>dag--dag_schedule_asset_name_reference</title> <path fill="none" stroke="#7f7f7f" stroke-dasharray="5,2" d="M758.83,-1608.26C797.89,-1544.61 845.49,-1482.86 902,-1435.5 905.96,-1432.18 910.1,-1429.03 914.38,-1426.03"/> <text text-anchor="start" x="883.38" y="-1429.83" font-family="Times,serif" font-size="14.00">0..N</text> <text text-anchor="start" x="748.83" y="-1597.06" font-family="Times,serif" font-size="14.00">1</text> </g> <!-- dag_schedule_asset_uri_reference --> -<g id="node26" class="node"> +<g id="node27" class="node"> <title>dag_schedule_asset_uri_reference</title> <polygon fill="none" stroke="black" points="926.5,-1949.5 926.5,-1977.5 1241.5,-1977.5 1241.5,-1949.5 926.5,-1949.5"/> <text text-anchor="start" x="931.5" y="-1960.7" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="16.00">dag_schedule_asset_uri_reference</text> @@ -1559,58 +1605,12 @@ <text text-anchor="start" x="1105.5" y="-1884.3" font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text> </g> <!-- dag--dag_schedule_asset_uri_reference --> -<g id="edge17" class="edge"> +<g id="edge18" class="edge"> <title>dag--dag_schedule_asset_uri_reference</title> <path fill="none" stroke="#7f7f7f" stroke-dasharray="5,2" d="M829.26,-1926.5C858.92,-1926.5 889.07,-1926.5 917.73,-1926.5"/> <text text-anchor="start" x="886.73" y="-1915.3" font-family="Times,serif" font-size="14.00">0..N</text> <text text-anchor="start" x="829.26" y="-1915.3" font-family="Times,serif" font-size="14.00">1</text> </g> -<!-- dag_version --> -<g id="node27" class="node"> -<title>dag_version</title> -<polygon fill="none" stroke="black" points="943.5,-2178.5 943.5,-2206.5 1224.5,-2206.5 1224.5,-2178.5 943.5,-2178.5"/> -<text text-anchor="start" x="1029.5" y="-2189.7" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="16.00">dag_version</text> -<polygon fill="none" stroke="black" points="943.5,-2153.5 943.5,-2178.5 1224.5,-2178.5 1224.5,-2153.5 943.5,-2153.5"/> -<text text-anchor="start" x="948.5" y="-2163.3" font-family="Helvetica,sans-Serif" text-decoration="underline" font-size="14.00">id</text> -<text text-anchor="start" x="961.5" y="-2163.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> -<text text-anchor="start" x="966.5" y="-2163.3" font-family="Helvetica,sans-Serif" font-size="14.00"> [UUID]</text> -<text text-anchor="start" x="1018.5" y="-2163.3" font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text> -<polygon fill="none" stroke="black" points="943.5,-2128.5 943.5,-2153.5 1224.5,-2153.5 1224.5,-2128.5 943.5,-2128.5"/> -<text text-anchor="start" x="948.5" y="-2138.3" font-family="Helvetica,sans-Serif" font-size="14.00">bundle_name</text> -<text text-anchor="start" x="1042.5" y="-2138.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> -<text text-anchor="start" x="1047.5" y="-2138.3" font-family="Helvetica,sans-Serif" font-size="14.00"> [VARCHAR(250)]</text> -<polygon fill="none" stroke="black" points="943.5,-2103.5 943.5,-2128.5 1224.5,-2128.5 1224.5,-2103.5 943.5,-2103.5"/> -<text text-anchor="start" x="948.5" y="-2113.3" font-family="Helvetica,sans-Serif" font-size="14.00">bundle_version</text> -<text text-anchor="start" x="1054.5" y="-2113.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> -<text text-anchor="start" x="1059.5" y="-2113.3" font-family="Helvetica,sans-Serif" font-size="14.00"> [VARCHAR(250)]</text> -<polygon fill="none" stroke="black" points="943.5,-2078.5 943.5,-2103.5 1224.5,-2103.5 1224.5,-2078.5 943.5,-2078.5"/> -<text text-anchor="start" x="948.5" y="-2088.3" font-family="Helvetica,sans-Serif" font-size="14.00">created_at</text> -<text text-anchor="start" x="1021.5" y="-2088.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> -<text text-anchor="start" x="1026.5" y="-2088.3" font-family="Helvetica,sans-Serif" font-size="14.00"> [TIMESTAMP]</text> -<text text-anchor="start" x="1122.5" y="-2088.3" font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text> -<polygon fill="none" stroke="black" points="943.5,-2053.5 943.5,-2078.5 1224.5,-2078.5 1224.5,-2053.5 943.5,-2053.5"/> -<text text-anchor="start" x="948.5" y="-2063.3" font-family="Helvetica,sans-Serif" font-size="14.00">dag_id</text> -<text text-anchor="start" x="994.5" y="-2063.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> -<text text-anchor="start" x="999.5" y="-2063.3" font-family="Helvetica,sans-Serif" font-size="14.00"> [VARCHAR(250)]</text> -<text text-anchor="start" x="1120.5" y="-2063.3" font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text> -<polygon fill="none" stroke="black" points="943.5,-2028.5 943.5,-2053.5 1224.5,-2053.5 1224.5,-2028.5 943.5,-2028.5"/> -<text text-anchor="start" x="948.5" y="-2038.3" font-family="Helvetica,sans-Serif" font-size="14.00">last_updated</text> -<text text-anchor="start" x="1038.5" y="-2038.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> -<text text-anchor="start" x="1043.5" y="-2038.3" font-family="Helvetica,sans-Serif" font-size="14.00"> [TIMESTAMP]</text> -<text text-anchor="start" x="1139.5" y="-2038.3" font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text> -<polygon fill="none" stroke="black" points="943.5,-2003.5 943.5,-2028.5 1224.5,-2028.5 1224.5,-2003.5 943.5,-2003.5"/> -<text text-anchor="start" x="948.5" y="-2013.3" font-family="Helvetica,sans-Serif" font-size="14.00">version_number</text> -<text text-anchor="start" x="1061.5" y="-2013.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> -<text text-anchor="start" x="1066.5" y="-2013.3" font-family="Helvetica,sans-Serif" font-size="14.00"> [INTEGER]</text> -<text text-anchor="start" x="1143.5" y="-2013.3" font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text> -</g> -<!-- dag--dag_version --> -<g id="edge22" class="edge"> -<title>dag--dag_version</title> -<path fill="none" stroke="#7f7f7f" stroke-dasharray="5,2" d="M829.26,-2007.49C864.9,-2021.28 901.24,-2035.35 934.86,-2048.36"/> -<text text-anchor="start" x="903.86" y="-2037.16" font-family="Times,serif" font-size="14.00">0..N</text> -<text text-anchor="start" x="829.26" y="-1996.29" font-family="Times,serif" font-size="14.00">1</text> -</g> <!-- dag_tag --> <g id="node28" class="node"> <title>dag_tag</title> diff --git a/airflow-core/src/airflow/migrations/versions/0042_3_0_0_add_uuid_primary_key_to_task_instance_.py b/airflow-core/src/airflow/migrations/versions/0042_3_0_0_add_uuid_primary_key_to_task_instance_.py index 3f4d5c4e926..ccd0697ff63 100644 --- a/airflow-core/src/airflow/migrations/versions/0042_3_0_0_add_uuid_primary_key_to_task_instance_.py +++ b/airflow-core/src/airflow/migrations/versions/0042_3_0_0_add_uuid_primary_key_to_task_instance_.py @@ -223,7 +223,9 @@ def upgrade(): """ ).bindparams(batch_size=batch_size) ) - row_count = result.rowcount + row_count = 0 + if result: + row_count = result.rowcount if row_count == 0: break print(f"Migrated {row_count} task_instance rows in this batch...") diff --git a/airflow-core/src/airflow/utils/db.py b/airflow-core/src/airflow/utils/db.py index e4919d82bfd..c492a508473 100644 --- a/airflow-core/src/airflow/utils/db.py +++ b/airflow-core/src/airflow/utils/db.py @@ -1210,7 +1210,8 @@ def downgrade(*, to_revision, from_revision=None, show_sql_only=False, session: config = _get_alembic_config() # Check if downgrade is less than 3.0.0 and requires that `ab_user` fab table is present if _revision_greater(config, _REVISION_HEADS_MAP["3.0.0"], to_revision): - if conf.getboolean("core", "unit_test_mode"): + unitest_mode = conf.getboolean("core", "unit_test_mode") + if unitest_mode: try: from airflow.providers.fab.auth_manager.models.db import FABDBManager @@ -1218,13 +1219,12 @@ def downgrade(*, to_revision, from_revision=None, show_sql_only=False, session: dbm.initdb() except ImportError: log.warning("Import error occurred while importing FABDBManager. Skipping the check.") - pass - if not inspect(settings.engine).has_table("ab_user"): - log.error( + return + if not inspect(settings.engine).has_table("ab_user") and not unitest_mode: + raise AirflowException( "Downgrade to revision less than 3.0.0 requires that `ab_user` table is present. " "Please add FabDBManager to [core] external_db_managers and run fab migrations before proceeding" ) - return with create_global_lock(session=session, lock=DBLocks.MIGRATIONS): if show_sql_only: log.warning("Generating sql scripts for manual migration.") diff --git a/airflow-core/tests/unit/utils/test_db.py b/airflow-core/tests/unit/utils/test_db.py index 05186d573f0..cf692750253 100644 --- a/airflow-core/tests/unit/utils/test_db.py +++ b/airflow-core/tests/unit/utils/test_db.py @@ -34,6 +34,7 @@ from alembic.runtime.environment import EnvironmentContext from alembic.script import ScriptDirectory from sqlalchemy import Column, Integer, MetaData, Table, select +from airflow.exceptions import AirflowException from airflow.models import Base as airflow_base from airflow.providers.fab.auth_manager.models.db import FABDBManager from airflow.settings import engine @@ -295,10 +296,12 @@ class TestDb: @conf_vars({("core", "unit_test_mode"): "False"}) @mock.patch("airflow.utils.db.inspect") - def test_upgradedb_raises_if_lower_than_v3_0_0(self, mock_inspect, caplog): + def test_downgrade_raises_if_lower_than_v3_0_0_and_no_ab_user(self, mock_inspect): mock_inspect.return_value.has_table.return_value = False - downgrade(to_revision=_REVISION_HEADS_MAP["2.7.0"]) - assert ( + msg = ( "Downgrade to revision less than 3.0.0 requires that `ab_user` table is present. " - "Please add FabDBManager to [core] external_db_managers and run fab migrations before proceeding" - ) in caplog.text + "Please add FabDBManager to [core] external_db_managers and run fab migrations before " + "proceeding" + ) + with pytest.raises(AirflowException, match=re.escape(msg)): + downgrade(to_revision=_REVISION_HEADS_MAP["2.7.0"])