Skip to content

chore: support sqlalchemy 2.x and flask-sqlalchemy 3 (breaking) - #2241

Merged
dpgaspar merged 124 commits into
masterfrom
danielgaspar/sc-80567/bump-fab-to-sqlalchemy-2
Sep 1, 2025
Merged

chore: support sqlalchemy 2.x and flask-sqlalchemy 3 (breaking)#2241
dpgaspar merged 124 commits into
masterfrom
danielgaspar/sc-80567/bump-fab-to-sqlalchemy-2

Conversation

@dpgaspar

@dpgaspar dpgaspar commented May 16, 2024

Copy link
Copy Markdown
Owner

Flask-AppBuilder 5.0.0 - Breaking Changes Release

This major release introduces SQLAlchemy 2.x support alongside 1.4.x compatibility and includes several breaking changes to improve the framework's architecture and compatibility with the modern Flask ecosystem.

Breaking Changes

1. Session Access Changes

Breaking: Session access method has been renamed.

Before:

session = appbuilder.sm.get_session

After:

session = appbuilder.sm.session

2. Application Context Requirements

Breaking: Database queries now require application context (consistent with Flask-SQLAlchemy behavior).

with app.app_context():
    users = appbuilder.sm.get_all_users()

3. SQLAInterface Exception Handling

Breaking: SQLAInterface no longer swallows exceptions and accepts an optional commit parameter.

Before:

interface = SQLAInterface(MyModel)

After:

# With automatic commit (default behavior)
interface = SQLAInterface(MyModel)
interface.add(item)

# With manual commit control
interface = SQLAInterface(MyModel)
interface.add(item, commit=False)

4. Application Reference Changes

Breaking: appbuilder.get_app method has been removed.

Before:

app = appbuilder.get_app

After:

from flask import current_app
app = current_app  # Preferred
# or
app = appbuilder.app  # Deprecated but still available

5. Model Table Names

Breaking: All user models now require explicit __tablename__ attributes for SQLAlchemy 2.x compatibility.

Before:

class MyModel(Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False)

After:

class MyModel(Model):
    __tablename__ = 'my_model'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False)

6. New Configuration Options

New: FAB_CREATE_DB configuration option to control automatic table creation.

# Disable automatic FAB table creation
FAB_CREATE_DB = False

Migration Guide

Step 1: Add Table Names to Models

Ensure all your models have the __tablename__ SQLAlchemy attribute defined.

Step 2: Update Session Access

Replace all instances of appbuilder.sm.get_session with appbuilder.sm.session.

Step 3: Add Application Context

Ensure all database queries are wrapped in application context when needed.

Step 4: Update Application References

Replace appbuilder.get_app calls with current_app imports.

Step 5: Review Exception Handling

Update any code that relied on SQLAInterface swallowing exceptions.

Compatibility

  • SQLAlchemy: Supports both 1.4.x and 2.x
  • Flask-SQLAlchemy: Supports 2.4.0+ and 3.x
  • Flask: Supports 2.x and 3.x
  • Flask-Babel: Updated to support 4.0.0+

Utility Functions

The flask_appbuilder.utils.legacy.get_sqla_class() function helps maintain compatibility between SQLAlchemy versions and provides a smooth migration path.


ADDITIONAL INFORMATION

  • Introduces new feature
  • Removes existing feature
  • Changes the security db schema
  • Is CRUD MVC related
  • Is Auth, RBAC security related

This is a BREAKING CHANGE release - please review the migration guide carefully before upgrading.

@hasansezertasan

Copy link
Copy Markdown

Related: #2240

@ddorian

ddorian commented May 21, 2024

Copy link
Copy Markdown

Also related #2038 #2162 #2108 #1940

@dpgaspar
dpgaspar marked this pull request as ready for review June 4, 2024 06:16
@dpgaspar dpgaspar changed the title chore: support sqlalchemy 2.x and flask-sqlalchemy 3 chore: support sqlalchemy 2.x and flask-sqlalchemy 3 (breaking) Jun 4, 2024
@potiuk

potiuk commented Jun 16, 2025

Copy link
Copy Markdown
Contributor

Also another question.. Have you thought about bumping flask to allow 3 as well? We have connexion, finally updating their old 2.* release to allow us to finally bump Werkzeug spec-first/connexion#1992 (comment) -> but it is flask 3+ only, so we cannot really do it before FAB can support Flask 3+.

@potiuk

potiuk commented Jul 8, 2025

Copy link
Copy Markdown
Contributor

Nice. I guess we should be able to revert some of our workarounds with @vincbeck :D

…my-2

# Conflicts:
#	flask_appbuilder/__init__.py
#	flask_appbuilder/api/__init__.py
#	flask_appbuilder/exceptions.py
Comment thread examples/quickminimal/run.py Dismissed
@dpgaspar

dpgaspar commented Aug 5, 2025

Copy link
Copy Markdown
Owner Author

Nice. I guess we should be able to revert some of our workarounds with @vincbeck :D

@potiuk

Sorry, for the delay here. But I've release 5.0.0a9 for early testing.

  • appbuilder will not take control of the SQLAlchemy singleton anymore, back to the current 4.X pattern
  • Supports Flask 3.X, needs flask-babel 4.0. Constraints will not enforce it, because we still support Flask 2

@potiuk

potiuk commented Aug 5, 2025

Copy link
Copy Markdown
Contributor

Sorry, for the delay here. But I've release 5.0.0a9 for early testing.
appbuilder will not take control of the SQLAlchemy singleton anymore, back to the current 4.X pattern
Supports Flask 3.X, needs flask-babel 4.0. Constraints will not enforce it, because we still support Flask 2

Fantastic. @vincbeck - seems that another round of testing for us ;)

Thanks @dpgaspar for the information

@vincbeck

vincbeck commented Aug 5, 2025

Copy link
Copy Markdown

Thanks @dpgaspar! Yep we go back to our PR and remove some (dirty) workarounds :)

@dpgaspar

dpgaspar commented Aug 5, 2025

Copy link
Copy Markdown
Owner Author

Thanks @dpgaspar! Yep we go back to our PR and remove some (dirty) workarounds :)

Great! I'll be reviving Superset's integration/PR. Tell me how the Airflow part went

@dpgaspar
dpgaspar requested a review from potiuk August 13, 2025 09:12
@dpgaspar
dpgaspar merged commit 2d5fa08 into master Sep 1, 2025
11 checks passed
@vincbeck

Copy link
Copy Markdown

Thanks @dpgaspar! Yep we go back to our PR and remove some (dirty) workarounds :)

Great! I'll be reviving Superset's integration/PR. Tell me how the Airflow part went

This is great! Thanks @dpgaspar, I could successfully use the official flask-appbuilder 5 in apache/airflow#50960 and remove all the hacks and workarounds @potiuk and I implemented to handle the issue with sqlalchemy instance. Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.