Skip to content

Commit

Permalink
deprecate config/options that are replaced by engine configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
rsyring committed Apr 17, 2019
1 parent 078a04b commit 112fe40
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 13 deletions.
23 changes: 21 additions & 2 deletions docs/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,16 @@ A list of configuration keys currently understood by the extension:
on some Ubuntu versions) when used with
improper database defaults that specify
encoding-less databases.

**Deprecated** as of v2.4 and will be removed in v3.0.
``SQLALCHEMY_POOL_SIZE`` The size of the database pool. Defaults
to the engine's default (usually 5)
to the engine's default (usually 5).

**Deprecated** as of v2.4 and will be removed in v3.0.
``SQLALCHEMY_POOL_TIMEOUT`` Specifies the connection timeout in seconds
for the pool.

**Deprecated** as of v2.4 and will be removed in v3.0.
``SQLALCHEMY_POOL_RECYCLE`` Number of seconds after which a
connection is automatically recycled.
This is required for MySQL, which removes
Expand All @@ -53,11 +59,15 @@ A list of configuration keys currently understood by the extension:
different default timeout value. For more
information about timeouts see
:ref:`timeouts`.

**Deprecated** as of v2.4 and will be removed in v3.0.
``SQLALCHEMY_MAX_OVERFLOW`` Controls the number of connections that
can be created after the pool reached
its maximum size. When those additional
connections are returned to the pool,
they are disconnected and discarded.

**Deprecated** as of v2.4 and will be removed in v3.0.
``SQLALCHEMY_TRACK_MODIFICATIONS`` If set to ``True``, Flask-SQLAlchemy will
track modifications of objects and emit
signals. The default is ``None``, which
Expand Down Expand Up @@ -88,7 +98,16 @@ A list of configuration keys currently understood by the extension:
``SQLALCHEMY_TRACK_MODIFICATIONS`` will warn if unset.

.. versionchanged:: 2.4
``SQLALCHEMY_ENGINE_OPTIONS`` configuration key was added.

* ``SQLALCHEMY_ENGINE_OPTIONS`` configuration key was added.
* Deprecated keys

* ``SQLALCHEMY_NATIVE_UNICODE``
* ``SQLALCHEMY_POOL_SIZE``
* ``SQLALCHEMY_POOL_TIMEOUT``
* ``SQLALCHEMY_POOL_RECYCLE``
* ``SQLALCHEMY_MAX_OVERFLOW``


Connection URI Format
---------------------
Expand Down
32 changes: 30 additions & 2 deletions flask_sqlalchemy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from flask_sqlalchemy.model import Model
from ._compat import itervalues, string_types, xrange
from .model import DefaultMeta
from . import utils

__version__ = '2.3.2'

Expand Down Expand Up @@ -634,13 +635,18 @@ def create_app():
the second case a :meth:`flask.Flask.app_context` has to exist.
By default Flask-SQLAlchemy will apply some backend-specific settings
to improve your experience with them. As of SQLAlchemy 0.6 SQLAlchemy
to improve your experience with them.
As of SQLAlchemy 0.6 SQLAlchemy
will probe the library for native unicode support. If it detects
unicode it will let the library handle that, otherwise do that itself.
Sometimes this detection can fail in which case you might want to set
``use_native_unicode`` (or the ``SQLALCHEMY_NATIVE_UNICODE`` configuration
key) to ``False``. Note that the configuration key overrides the
value you pass to the constructor.
value you pass to the constructor. Direct support for ``use_native_unicode``
and SQLALCHEMY_NATIVE_UNICODE are deprecated as of v2.4 and will be removed
in v3.0. ``engine_options`` and ``SQLALCHEMY_ENGINE_OPTIONS`` may be used
instead.
This class also provides access to all the SQLAlchemy functions and classes
from the :mod:`sqlalchemy` and :mod:`sqlalchemy.orm` modules. So you can
Expand Down Expand Up @@ -696,6 +702,9 @@ class to be used in place of :class:`Model`.
.. versionadded:: 2.4
The `engine_options` parameter was added.
.. versionchanged:: 2.4
The `use_native_unicode` parameter was deprecated.
"""

#: Default query class used by :attr:`Model.query` and other queries.
Expand Down Expand Up @@ -834,6 +843,12 @@ def init_app(self, app):
'or False to suppress this warning.'
))

# Deprecation warnings for config keys that should be replaced by SQLALCHEMY_ENGINE_OPTIONS.
utils.engine_config_warning(app.config, '3.0', 'SQLALCHEMY_POOL_SIZE', 'pool_size')
utils.engine_config_warning(app.config, '3.0', 'SQLALCHEMY_POOL_TIMEOUT', 'pool_timeout')
utils.engine_config_warning(app.config, '3.0', 'SQLALCHEMY_POOL_RECYCLE', 'pool_recycle')
utils.engine_config_warning(app.config, '3.0', 'SQLALCHEMY_MAX_OVERFLOW', 'max_overflow')

app.extensions['sqlalchemy'] = _SQLAlchemyState(self)

@app.teardown_appcontext
Expand Down Expand Up @@ -904,6 +919,19 @@ def apply_driver_hacks(self, app, sa_url, options):
if not unu:
options['use_native_unicode'] = False

if app.config['SQLALCHEMY_NATIVE_UNICODE'] is not None:
warnings.warn(
"The 'SQLALCHEMY_NATIVE_UNICODE' config option is deprecated and will be removed in"
" v3.0. Use 'SQLALCHEMY_ENGINE_OPTIONS' instead.",
DeprecationWarning
)
if not self.use_native_unicode:
warnings.warn(
"'use_native_unicode' is deprecated and will be removed in v3.0."
" Use the 'engine_options' parameter instead.",
DeprecationWarning
)

@property
def engine(self):
"""Gives access to the engine. If the database configuration is bound
Expand Down
11 changes: 11 additions & 0 deletions flask_sqlalchemy/utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import warnings

import sqlalchemy

Expand Down Expand Up @@ -32,3 +33,13 @@ def sqlalchemy_version(op, val):
if op == '>=':
return sa_ver >= target_ver
return sa_ver == target_ver


def engine_config_warning(config, version, deprecated_config_key, engine_option):
if config[deprecated_config_key] is not None:
warnings.warn(
'The `{}` config option is deprecated and will be removed in'
' v{}. Use `SQLALCHEMY_ENGINE_OPTIONS[\'{}\']` instead.'
.format(deprecated_config_key, version, engine_option),
DeprecationWarning
)
81 changes: 72 additions & 9 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@
from flask_sqlalchemy import _compat, utils


@pytest.fixture
def app_nr(app):
"""
Signal/event registration with record queries breaks when
sqlalchemy.create_engine() is mocked out.
"""
app.config['SQLALCHEMY_RECORD_QUERIES'] = False
return app


class TestConfigKeys:

def test_defaults(self, app):
Expand Down Expand Up @@ -81,15 +91,68 @@ def test_engine_creation_ok(self, app, recwarn):

assert len(recwarn) == expected_warnings

@mock.patch.object(fsa.sqlalchemy, 'create_engine', autospec=True, spec_set=True)
def test_native_unicode_deprecation_config_opt(self, m_create_engine, app_nr, recwarn):
app_nr.config['SQLALCHEMY_NATIVE_UNICODE'] = False
assert fsa.SQLAlchemy(app_nr).get_engine()
assert len(recwarn) == 1

@pytest.fixture
def app_nr(app):
"""
Signal/event registration with record queries breaks when
sqlalchemy.create_engine() is mocked out.
"""
app.config['SQLALCHEMY_RECORD_QUERIES'] = False
return app
warning_msg = recwarn[0].message.args[0]
assert 'SQLALCHEMY_NATIVE_UNICODE' in warning_msg
assert 'deprecated and will be removed in v3.0' in warning_msg

@mock.patch.object(fsa.sqlalchemy, 'create_engine', autospec=True, spec_set=True)
def test_native_unicode_deprecation_init_opt(self, m_create_engine, app_nr, recwarn):
assert fsa.SQLAlchemy(app_nr, use_native_unicode=False).get_engine()
assert len(recwarn) == 1

warning_msg = recwarn[0].message.args[0]
assert 'use_native_unicode' in warning_msg
assert 'deprecated and will be removed in v3.0' in warning_msg

@mock.patch.object(fsa.sqlalchemy, 'create_engine', autospec=True, spec_set=True)
def test_deprecation_config_opt_pool_size(self, m_create_engine, app_nr, recwarn):
app_nr.config['SQLALCHEMY_POOL_SIZE'] = 5
assert fsa.SQLAlchemy(app_nr).get_engine()
assert len(recwarn) == 1

warning_msg = recwarn[0].message.args[0]
assert 'SQLALCHEMY_POOL_SIZE' in warning_msg
assert 'deprecated and will be removed in v3.0.' in warning_msg
assert 'pool_size' in warning_msg

@mock.patch.object(fsa.sqlalchemy, 'create_engine', autospec=True, spec_set=True)
def test_deprecation_config_opt_pool_timeout(self, m_create_engine, app_nr, recwarn):
app_nr.config['SQLALCHEMY_POOL_TIMEOUT'] = 5
assert fsa.SQLAlchemy(app_nr).get_engine()
assert len(recwarn) == 1

warning_msg = recwarn[0].message.args[0]
assert 'SQLALCHEMY_POOL_TIMEOUT' in warning_msg
assert 'deprecated and will be removed in v3.0.' in warning_msg
assert 'pool_timeout' in warning_msg

@mock.patch.object(fsa.sqlalchemy, 'create_engine', autospec=True, spec_set=True)
def test_deprecation_config_opt_pool_recycle(self, m_create_engine, app_nr, recwarn):
app_nr.config['SQLALCHEMY_POOL_RECYCLE'] = 5
assert fsa.SQLAlchemy(app_nr).get_engine()
assert len(recwarn) == 1

warning_msg = recwarn[0].message.args[0]
assert 'SQLALCHEMY_POOL_RECYCLE' in warning_msg
assert 'deprecated and will be removed in v3.0.' in warning_msg
assert 'pool_recycle' in warning_msg

@mock.patch.object(fsa.sqlalchemy, 'create_engine', autospec=True, spec_set=True)
def test_deprecation_config_opt_max_overflow(self, m_create_engine, app_nr, recwarn):
app_nr.config['SQLALCHEMY_MAX_OVERFLOW'] = 5
assert fsa.SQLAlchemy(app_nr).get_engine()
assert len(recwarn) == 1

warning_msg = recwarn[0].message.args[0]
assert 'SQLALCHEMY_MAX_OVERFLOW' in warning_msg
assert 'deprecated and will be removed in v3.0.' in warning_msg
assert 'max_overflow' in warning_msg


@mock.patch.object(fsa.sqlalchemy, 'create_engine', autospec=True, spec_set=True)
Expand Down Expand Up @@ -139,7 +202,7 @@ def test_pool_class_default(self, m_create_engine, app_nr):
args, options = m_create_engine.call_args
assert options['poolclass'].__name__ == 'StaticPool'

def test_pool_class_with_pool_size_zero(self, m_create_engine, app_nr):
def test_pool_class_with_pool_size_zero(self, m_create_engine, app_nr, recwarn):
app_nr.config['SQLALCHEMY_POOL_SIZE'] = 0
with pytest.raises(RuntimeError) as exc_info:
fsa.SQLAlchemy(app_nr).get_engine()
Expand Down

0 comments on commit 112fe40

Please sign in to comment.