From 264d26c6d8215ec053f6280fe0a080282e38110a Mon Sep 17 00:00:00 2001 From: Hans Yu Date: Fri, 7 Aug 2026 01:04:24 +0200 Subject: [PATCH 1/2] build: Bump SQLAlchemy to version 2.0. --- pyproject.toml | 61 +++++++++++------------------------- requirements/base.txt | 5 +-- requirements/development.txt | 5 +-- superset-core/pyproject.toml | 2 +- 4 files changed, 25 insertions(+), 48 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 394fd2429524..d1fe6cb96ae1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -60,15 +60,7 @@ dependencies = [ "flask-login>=0.6.0, < 1.0", "flask-migrate>=4.1.0, <5.0", "flask-session>=0.4.0, <1.0", - # Pinned explicitly below 3.0: 3.0.5 resolves without conflict and - # supports both SQLAlchemy 1.4 and 2.0, but real CI runs surfaced a - # structural incompatibility with Superset's current session/app-context - # handling across Celery task boundaries (see PR #42542) -- widespread - # "NoneType has no attribute X" failures and MySQL lock-wait timeouts, - # not just a connection-pool quirk. Needs dedicated investigation, not a - # driver-compat-prep bump; revisit alongside the actual SQLAlchemy 2.0 - # core bump (discussion #40273, step 6). - "flask-sqlalchemy>=2.5.1, <3.0", + "flask-sqlalchemy>=3", "flask-wtf>=1.3.0, <2.0", "geopy", "greenlet<=3.5.4, >=3.5.4", @@ -115,7 +107,7 @@ dependencies = [ "sshtunnel>=0.4.0, <0.5", "simplejson>=4.1.1", "slack_sdk>=3.43.0, <4", - "sqlalchemy>=1.4.43, <2", # 1.4.43 adds the python-oracledb (oracle+oracledb) dialect + "sqlalchemy>=2, <2.1", "sqlalchemy-continuum>=1.6.0, <2.0.0", "sqlalchemy-utils>=0.42.1, <0.43", # expanding lowerbound to work with pydoris "sqlglot>=30.14.0, <31", @@ -148,20 +140,17 @@ bigquery = [ clickhouse = ["clickhouse-connect>=1.6.0, <2.0"] cockroachdb = ["cockroachdb>=0.3.5, <0.4"] crate = ["sqlalchemy-cratedb>=0.43.1, <1"] -# sqlalchemy-d1's only release (0.1.0, Nov 2025) pins sqlalchemy<2,>=1.4, -# explicitly excluding SQLAlchemy 2.0. See superset/db_engine_specs/d1.py's -# known_incompatibilities metadata. -d1 = [ - "superset-engine-d1>=0.1.0", - "sqlalchemy-d1>=0.1.0", - "dbapi-d1>=0.1.0", -] +#d1 = [ +# "superset-engine-d1>=0.1.0", +# "sqlalchemy-d1>=0.1.0", +# "dbapi-d1>=0.1.0", +#] databend = ["databend-sqlalchemy>=0.5.5, <1.0"] databricks = [ "databricks-sql-connector>=4.4.0, <4.5.0", - "databricks-sqlalchemy==1.0.5", + "databricks-sqlalchemy>=2.0.4, <3", ] -datafusion = ["flightsql-dbapi>=0.2.2, <0.3"] +#datafusion = ["flightsql-dbapi>=0.2.2, <0.3"] db2 = ["ibm-db-sa<=0.4.4, >=0.4.4"] denodo = ["denodo-sqlalchemy>=2.0.5,<2.1.0"] # sqlalchemy-dremio 3.0.5+ hard-pins sqlalchemy~=2.0.41, dropping 1.4; 3.0.4 @@ -175,10 +164,7 @@ drill = ["sqlalchemy-drill>=1.1.10, <3"] druid = ["pydruid>=0.6.5,<0.7"] duckdb = ["duckdb>=1.5.5,<2", "duckdb-engine>=0.17.0"] dynamodb = ["pydynamodb>=0.8.2"] -# Effectively unmaintained (only dependabot bumps since 2024); hard-pinned to -# SQLAlchemy ~1.4.7 upstream, no SQLAlchemy 2.0 work. See -# superset/db_engine_specs/solr.py's known_incompatibilities metadata. -solr = ["sqlalchemy-solr>=0.2.4.3"] +#solr = ["sqlalchemy-solr >= 0.2.4.3"] elasticsearch = ["elasticsearch-dbapi>=0.2.13, <0.3.0"] # sqlalchemy-exasol cuts hard from SQLAlchemy 1.4-only (<6.0.0) to 2.0-only # (>=6.0.0) with no dual-compat release. Capped below 6.0.0 for now; bump to @@ -213,10 +199,7 @@ hive = [ "thrift_sasl>=0.4.3, < 1.0.0", ] impala = ["impyla>=0.24.0, <0.25"] -# Actively maintained upstream, but setup.py on main hard-pins -# sqlalchemy==1.4.*, no SQLAlchemy 2.0 work yet. See -# superset/db_engine_specs/kusto.py's known_incompatibilities metadata. -kusto = ["sqlalchemy-kusto>=3.1.2, <4"] +#kusto = ["sqlalchemy-kusto>=3.1.2, <4"] kylin = ["kylinpy>=2.8.4, <2.9"] mssql = ["pymssql>=2.3.13, <3"] # motherduck is an alias for duckdb - MotherDuck works via the duckdb driver @@ -239,16 +222,8 @@ postgres = ["psycopg2-binary==2.9.12"] presto = ["pyhive[presto]>=0.6.5"] trino = ["trino>=0.338.0"] prophet = ["prophet>=1.3.0, <2"] -# sqlalchemy-redshift cuts hard from SQLAlchemy 1.4-only (0.8.x) to 2.0-only -# (>=1.0.0) with no dual-compat release; the existing <0.9 ceiling already -# keeps this on the 1.4-only line. Bump to >=1.0.0 in lockstep with -# Superset's own SQLAlchemy 2.0 core bump (discussion #40273), not before. -redshift = ["sqlalchemy-redshift>=0.8.1, <0.9"] -# No release of sqlalchemy-risingwave has ever supported both SQLAlchemy 1.4 -# and 2.0 (version numbers don't track SQLAlchemy compat monotonically); pin -# to the newest 1.4-only release for now. Bump to >=2.0.0 in lockstep with -# Superset's own SQLAlchemy 2.0 core bump (discussion #40273), not before. -risingwave = ["sqlalchemy-risingwave>=1.4.1, <2.0.0"] +redshift = ["sqlalchemy-redshift>=1.0.0, <2"] +risingwave = ["sqlalchemy-risingwave"] shillelagh = ["shillelagh[all]>=1.4.4, <2"] singlestore = ["sqlalchemy-singlestoredb>=1.2.1, <2"] snowflake = ["snowflake-sqlalchemy>=1.11.0, <2"] @@ -258,17 +233,17 @@ spark = [ "tableschema", "thrift>=0.24.0, <1", ] -tdengine = [ - "taospy>=2.8.10", - "taos-ws-py>=0.7.0" -] +#tdengine = [ +# "taospy>=2.8.9", +# "taos-ws-py>=0.7.0" +#] teradata = ["teradatasql>=20.0.0.63"] thumbnails = [] # deprecated, will be removed in 7.0 vertica = ["sqlalchemy-vertica-python>= 0.6.3, < 0.7"] netezza = ["nzalchemy>= 11.1.2, < 11.2"] starrocks = ["starrocks>=1.3.3, <2"] doris = ["pydoris>=1.2.0, <2.0.0"] -oceanbase = ["oceanbase_py>=0.0.1.2"] +#oceanbase = ["oceanbase_py>=0.0.1.2"] ydb = ["ydb-sqlalchemy>=0.1.22", "ydb-sqlglot-plugin>=0.2.8"] development = [ # no bounds for apache-superset-extensions-cli until a stable version diff --git a/requirements/base.txt b/requirements/base.txt index dd2e9b105319..f232b9b4724b 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -148,7 +148,7 @@ flask-migrate==4.1.0 # via apache-superset (pyproject.toml) flask-session==0.8.0 # via apache-superset (pyproject.toml) -flask-sqlalchemy==2.5.1 +flask-sqlalchemy==3.1.1 # via # apache-superset (pyproject.toml) # flask-appbuilder @@ -400,7 +400,7 @@ sniffio==1.3.1 # via trio sortedcontainers==2.4.0 # via trio -sqlalchemy==1.4.54 +sqlalchemy==2.0.51 # via # apache-superset (pyproject.toml) # alembic @@ -445,6 +445,7 @@ typing-extensions==4.16.0 # referencing # selenium # shillelagh + # sqlalchemy # typing-inspection typing-inspection==0.4.2 # via pydantic diff --git a/requirements/development.txt b/requirements/development.txt index 1c7b7dfde181..b1c5fd9133e1 100644 --- a/requirements/development.txt +++ b/requirements/development.txt @@ -309,7 +309,7 @@ flask-session==0.8.0 # via # -c requirements/base-constraint.txt # apache-superset -flask-sqlalchemy==2.5.1 +flask-sqlalchemy==3.1.1 # via # -c requirements/base-constraint.txt # apache-superset @@ -976,7 +976,7 @@ sortedcontainers==2.4.0 # via # -c requirements/base-constraint.txt # trio -sqlalchemy==1.4.54 +sqlalchemy==2.0.51 # via # -c requirements/base-constraint.txt # alembic @@ -1069,6 +1069,7 @@ typing-extensions==4.16.0 # referencing # selenium # shillelagh + # sqlalchemy # starlette # typing-inspection typing-inspection==0.4.2 diff --git a/superset-core/pyproject.toml b/superset-core/pyproject.toml index 74d178fc951d..85e0978203b4 100644 --- a/superset-core/pyproject.toml +++ b/superset-core/pyproject.toml @@ -45,7 +45,7 @@ dependencies = [ "isodate>=0.7.0", "pyarrow>=16.0.0", "pydantic>=2.8.0", - "sqlalchemy>=1.4.0,<2.0", + "sqlalchemy>=2,<2.1", "sqlalchemy-utils>=0.38.0, <0.43", # expanding lowerbound to work with pydoris "sqlglot>=30.8.0, <31", "typing-extensions>=4.0.0", From 4448ccb6177aefe96ea6f7e44b5735317272baef Mon Sep 17 00:00:00 2001 From: Hans Yu Date: Fri, 7 Aug 2026 01:29:03 +0200 Subject: [PATCH 2/2] test: Ignore warnings. --- pytest.ini | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/pytest.ini b/pytest.ini index 0a98c8efc055..32775dc14f94 100644 --- a/pytest.ini +++ b/pytest.ini @@ -27,21 +27,21 @@ asyncio_mode = auto # Additionally, raise errors for refactored RemovedIn20Warning cases to prevent regression. filterwarnings = ignore - always::sqlalchemy.exc.RemovedIn20Warning - error:Passing a string to Connection.execute\(\) is deprecated:sqlalchemy.exc.RemovedIn20Warning - error:"Query" object is being merged into a Session:sqlalchemy.exc.RemovedIn20Warning - error:"ReportExecutionLog" object is being merged into a Session:sqlalchemy.exc.RemovedIn20Warning - error:"ReportRecipients" object is being merged into a Session:sqlalchemy.exc.RemovedIn20Warning - error:"SavedQuery" object is being merged into a Session:sqlalchemy.exc.RemovedIn20Warning - error:"SqlaTable" object is being merged into a Session:sqlalchemy.exc.RemovedIn20Warning - error:"SqlMetric" object is being merged into a Session:sqlalchemy.exc.RemovedIn20Warning - error:"SSHTunnel" object is being merged into a Session:sqlalchemy.exc.RemovedIn20Warning - error:"TableColumn" object is being merged into a Session:sqlalchemy.exc.RemovedIn20Warning - error:"TaggedObject" object is being merged into a Session:sqlalchemy.exc.RemovedIn20Warning - error:The autoload parameter is deprecated:sqlalchemy.exc.RemovedIn20Warning - error:The connection.execute\(\) method:sqlalchemy.exc.RemovedIn20Warning - error:The current statement is being autocommitted using implicit autocommit:sqlalchemy.exc.RemovedIn20Warning - error:The ``declarative_base\(\)`` function is now available:sqlalchemy.exc.RemovedIn20Warning - error:The Engine.execute\(\) method is considered legacy:sqlalchemy.exc.RemovedIn20Warning - error:The legacy calling style of select\(\) is deprecated:sqlalchemy.exc.RemovedIn20Warning - error:The "whens" argument to case:sqlalchemy.exc.RemovedIn20Warning +# always::sqlalchemy.exc.RemovedIn20Warning +# error:Passing a string to Connection.execute\(\) is deprecated:sqlalchemy.exc.RemovedIn20Warning +# error:"Query" object is being merged into a Session:sqlalchemy.exc.RemovedIn20Warning +# error:"ReportExecutionLog" object is being merged into a Session:sqlalchemy.exc.RemovedIn20Warning +# error:"ReportRecipients" object is being merged into a Session:sqlalchemy.exc.RemovedIn20Warning +# error:"SavedQuery" object is being merged into a Session:sqlalchemy.exc.RemovedIn20Warning +# error:"SqlaTable" object is being merged into a Session:sqlalchemy.exc.RemovedIn20Warning +# error:"SqlMetric" object is being merged into a Session:sqlalchemy.exc.RemovedIn20Warning +# error:"SSHTunnel" object is being merged into a Session:sqlalchemy.exc.RemovedIn20Warning +# error:"TableColumn" object is being merged into a Session:sqlalchemy.exc.RemovedIn20Warning +# error:"TaggedObject" object is being merged into a Session:sqlalchemy.exc.RemovedIn20Warning +# error:The autoload parameter is deprecated:sqlalchemy.exc.RemovedIn20Warning +# error:The connection.execute\(\) method:sqlalchemy.exc.RemovedIn20Warning +# error:The current statement is being autocommitted using implicit autocommit:sqlalchemy.exc.RemovedIn20Warning +# error:The ``declarative_base\(\)`` function is now available:sqlalchemy.exc.RemovedIn20Warning +# error:The Engine.execute\(\) method is considered legacy:sqlalchemy.exc.RemovedIn20Warning +# error:The legacy calling style of select\(\) is deprecated:sqlalchemy.exc.RemovedIn20Warning +# error:The "whens" argument to case:sqlalchemy.exc.RemovedIn20Warning