diff --git a/airflow/utils/db.py b/airflow/utils/db.py index 5748adf0e46e6..5efa382a54dc7 100644 --- a/airflow/utils/db.py +++ b/airflow/utils/db.py @@ -1458,7 +1458,8 @@ def check_query_exists(query_stmt: Select, *, session: Session) -> bool: :meta private: """ count_stmt = select(literal(True)).select_from(query_stmt.order_by(None).subquery()) - return session.scalar(count_stmt) + # we must cast to bool because scalar() can return None + return bool(session.scalar(count_stmt)) def exists_query(*where: ClauseElement, session: Session) -> bool: diff --git a/tests/utils/test_db.py b/tests/utils/test_db.py index 1d3412d361412..471bdeecc1e37 100644 --- a/tests/utils/test_db.py +++ b/tests/utils/test_db.py @@ -32,11 +32,12 @@ from alembic.migration import MigrationContext from alembic.runtime.environment import EnvironmentContext from alembic.script import ScriptDirectory -from sqlalchemy import MetaData +from sqlalchemy import Column, Integer, MetaData, Table, select from airflow.models import Base as airflow_base from airflow.settings import engine from airflow.utils.db import ( + LazySelectSequence, _get_alembic_config, check_migrations, compare_server_default, @@ -251,3 +252,16 @@ def test_alembic_configuration(self): import airflow assert config.config_file_name == os.path.join(os.path.dirname(airflow.__file__), "alembic.ini") + + def test_bool_lazy_select_sequence(self): + class MockSession: + def __init__(self): + pass + + def scalar(self, stmt): + return None + + t = Table("t", MetaData(), Column("id", Integer, primary_key=True)) + lss = LazySelectSequence.from_select(select(t.c.id), order_by=[], session=MockSession()) + + assert bool(lss) is False