Drop support for Python 2, 3.4, 3.5, and 3.6.
Bump minimum version of Flask to 2.2.
Bump minimum version of SQLAlchemy to 1.4.18.
Remove previously deprecated code.
The session is scoped to the current app context instead of the thread. This requires that an app context is active. This ensures that the session is cleaned up after every request.
Different bind keys use different SQLAlchemy
MetaDataregistries, allowing tables in different databases to have the same name. Bind keys are stored and looked up on the resulting metadata rather than the model or table.
SQLALCHEMY_DATABASE_URIdoes not default to
sqlite:///:memory:. An error is raised if neither it nor
SQLALCHEMY_BINDSdefine any engines. #731
Configuring SQLite with a relative path is relative to
app.root_path. The instance folder is created if necessary. #462
paginatemethods to the extension object. These use SQLAlchemy’s preferred
session.execute(select())pattern instead of the legacy query interface. #1088
Setup methods that create the engines and session are renamed with a leading underscore. They are considered internal interfaces which may change at any time.
All parameters to
bind_keyand removed the
appparameter from various
The extension object uses
__getattr__to alias names from the SQLAlchemy package, rather than copying them as attributes.
The extension object is stored directly as
The session class can be customized by passing the
class_key in the
SignallingSessionis renamed to
Session.get_bindmore closely matches the base implementation.
Model classes and the
dbinstance are available without imports in
flask shell. #1089
snake_casetable name converter handles more patterns correctly. If such a that was was already created in the database changed, either use Alembic to rename the table, or set
__tablename__to keep the old name. #406
reprdistinguishes between transient and pending instances. #967
A custom model class can implement
__init_subclass__with class parameters. #1002
db.Tableis a subclass instead of a function.
engine_optionsparameter is applied as defaults before per-engine configuration.
SQLALCHEMY_BINDSvalues can either be an engine URL, or a dict of engine options including URL, for each bind.
SQLALCHEMY_ENGINE_OPTIONScorrespond to the
Nonekey and take precedence. #783
Engines are created when calling
init_apprather than the first time they are accessed. #698
db.enginesexposes the map of bind keys to engines for the current app.
SQLite engines do not use
MySQL engines use the “utf8mb4” charset by default. #875
MySQL engines do not set
MySQL engines don’t set a default for
pool_recycleif not using a queue pool. #803
Queryis renamed from
The query class is applied to
Paginationobjects manually is no longer a public API. They should be created with
Query.paginateparameters are keyword-only.
Paginationis iterable, iterating over its items. #70
Pagination count query is more efficient.
Pagination.iter_pagesis more efficient. #622
right_currentparameter is inclusive.
per_pagecannot be 0. #1091
max_per_pagedefaults to 100. #1091
lastproperties, which give the number of the first and last item on the page. #567
SQLALCHEMY_RECORD_QUERIESis disabled by default, and is not enabled automatically with
get_debug_queriesis renamed to
get_recorded_queriesto better match the config and functionality.
Recorded query info is a dataclass instead of a tuple. The
contextattribute is renamed to
location. Finding the location uses a more inclusive check.
SQLALCHEMY_TRACK_MODIFICATIONSis disabled by default. #727
SQLALCHEMY_COMMIT_ON_TEARDOWNis deprecated. It can cause various design issues that are difficult to debug. Call
db.session.commit()directly instead. #216
Fix compatibility with Python 2.7.
Update to support SQLAlchemy 1.4.
URLobjects are immutable. Some internal methods have changed to return a new URL instead of
Change base class of meta mixins to
type. This fixes an issue caused by a regression in CPython 3.8.4. #852
SQLALCHEMY_COMMIT_ON_TEARDOWNas it can cause various design issues that are difficult to debug. Call
db.session.commit()directly instead. #216
Fix bad pagination when records are de-duped. #812
AttributeErrorwhen using multiple binds with polymorphic models. #651
Make engine configuration more flexible. (#684)
Address SQLAlchemy 1.3 deprecations. (#684)
first_or_404()now accept a
descriptionparameter to control the 404 message. (#636)
time.perf_counterfor Python 3 on Windows. (#638)
Drop support for Python 2.6 and 3.3. (#687)
Add an example of Flask’s tutorial project, Flaskr, adapted for Flask-SQLAlchemy. (#720)
Don’t mask the parent table for single-table inheritance models. (#561)
If a model has a table name that matches an existing table in the metadata, use that table. Fixes a regression where reflected tables were not picked up by models. (#551)
Raise the correct error when a model has a table name but no primary key. (#556)
repron models that don’t have an identity because they have not been flushed yet. (#555)
Allow specifying a
max_per_pagelimit for pagination, to avoid users specifying high values in the request args. (#542)
error_out=False, the minimum value for
pageis 1 and
per_pageis 0. (#558)
Multiple bugs with
__tablename__generation are fixed. Names will be generated for models that define a primary key, but not for single-table inheritance subclasses. Names will not override a
PrimaryKeyConstraintis detected. (#541)
Passing an existing
SQLAlchemy.__init__will use this as the base class instead of creating one. This allows customizing the metaclass used to construct the base. (#546)
DeclarativeMetainternals that the extension uses for binds and table name generation have been refactored to work as mixins. Documentation is added about how to create a custom metaclass that does not do table name generation. (#546)
Model and metaclass code has been moved to a new
_BoundDeclarativeMetais renamed to
DefaultMeta; the old name will be removed in 3.0. (#546)
Models have a default
reprthat shows the model name and primary key. (#530)
Fixed a bug where using
init_appwould cause connectors to always use the
current_apprather than the app they were created for. This caused issues when multiple apps were registered with the extension. (#547)
Released 2017-02-27, codename Dubnium
Minimum SQLAlchemy version is 0.8 due to use of
Added support for custom
model_classas args to the
Allow listening to SQLAlchemy events on
__bind_key__on abstract models. (#373)
SQLALCHEMY_ECHOto be a string. (#409)
SQLALCHEMY_DATABASE_URIis not set. (#443)
Don’t let pagination generate invalid page numbers. (#460)
Drop support of Flask < 0.10. This means the db session is always tied to the app context and its teardown event. (#461)
Tablename generation logic no longer accesses class properties unless they are
Released 2015-10-23, codename Caesium
Table names are automatically generated in more cases, including subclassing mixins and abstract models.
Allow using a custom MetaData object.
Add support for binds parameter to session.
Released 2014-08-29, codename Bohrium
Changed how the builtin signals are subscribed to skip non-Flask-SQLAlchemy sessions. This will also fix the attribute error about model changes not existing.
Added a way to control how signals for model modifications are tracked.
SignallingSessiona public interface and added a hook for customizing session creation.
bindparameter is given to the signalling session it will no longer cause an error that a parameter is given twice.
Added working table reflection support.
Enabled autoflush by default.
SQLALCHEMY_COMMIT_ON_TEARDOWNharmful and remove from docs.
Released 2013-07-20, codename Aurum
Added Python 3.3 support.
Dropped 2.5 compatibility.
Changed versioning format to do major releases for each update now.
New distribution format (flask_sqlalchemy)
Added support for Flask 0.9 specifics.
Added session support for multiple databases.
Make relative sqlite paths relative to the application root.
Fixed an issue with Flask-SQLAlchemy not selecting the correct binds.
Added support for multiple databases.
Improved compatibility with Flask 0.7.
Fixed a bug introduced in 0.10 with alternative table constructors.
Added support for signals.
Table names are now automatically set from the class name unless overridden.
Model.querynow always works for applications directly passed to the
SQLAlchemyconstructor. Furthermore the property now raises a
RuntimeErrorinstead of being
Added session options to constructor.
Fixed a broken
db.Tableis now a factory function that creates table objects. This makes it possible to omit the metadata.
Applied changes to pass the Flask extension approval process.
Added a few configuration keys for creating connections.
Automatically activate connection recycling for MySQL connections.
Added support for the Flask testing mode.
Initial public release