diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-04-07 14:15:43 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-04-16 13:35:55 -0400 |
| commit | 2f617f56f2acdce00b88f746c403cf5ed66d4d27 (patch) | |
| tree | 0962f2c43c1a361135ecdab933167fa0963ae58a /lib/sqlalchemy/testing | |
| parent | bd303b10e2bf69169f07447c7272fc71ac931f10 (diff) | |
| download | sqlalchemy-2f617f56f2acdce00b88f746c403cf5ed66d4d27.tar.gz | |
Create initial 2.0 engine implementation
Implemented the SQLAlchemy 2 :func:`.future.create_engine` function which
is used for forwards compatibility with SQLAlchemy 2. This engine
features always-transactional behavior with autobegin.
Allow execution options per statement execution. This includes
that the before_execute() and after_execute() events now accept
an additional dictionary with these options, empty if not
passed; a legacy event decorator is added for backwards compatibility
which now also emits a deprecation warning.
Add some basic tests for execution, transactions, and
the new result object. Build out on a new testing fixture
that swaps in the future engine completely to start with.
Change-Id: I70e7338bb3f0ce22d2f702537d94bb249bd9fb0a
Fixes: #4644
Diffstat (limited to 'lib/sqlalchemy/testing')
| -rw-r--r-- | lib/sqlalchemy/testing/assertsql.py | 4 | ||||
| -rw-r--r-- | lib/sqlalchemy/testing/config.py | 8 | ||||
| -rw-r--r-- | lib/sqlalchemy/testing/engines.py | 7 | ||||
| -rw-r--r-- | lib/sqlalchemy/testing/fixtures.py | 23 | ||||
| -rw-r--r-- | lib/sqlalchemy/testing/suite/test_ddl.py | 6 | ||||
| -rw-r--r-- | lib/sqlalchemy/testing/warnings.py | 7 |
6 files changed, 51 insertions, 4 deletions
diff --git a/lib/sqlalchemy/testing/assertsql.py b/lib/sqlalchemy/testing/assertsql.py index 8876c2304..7988b4ec9 100644 --- a/lib/sqlalchemy/testing/assertsql.py +++ b/lib/sqlalchemy/testing/assertsql.py @@ -388,7 +388,9 @@ def assert_engine(engine): orig = [] @event.listens_for(engine, "before_execute") - def connection_execute(conn, clauseelement, multiparams, params): + def connection_execute( + conn, clauseelement, multiparams, params, execution_options + ): # grab the original statement + params before any cursor # execution orig[:] = clauseelement, multiparams, params diff --git a/lib/sqlalchemy/testing/config.py b/lib/sqlalchemy/testing/config.py index 140f5f782..e97821d72 100644 --- a/lib/sqlalchemy/testing/config.py +++ b/lib/sqlalchemy/testing/config.py @@ -150,6 +150,14 @@ class Config(object): cls.set_as_current(config, namespace) @classmethod + def pop(cls, namespace): + if cls._stack: + # a failed test w/ -x option can call reset() ahead of time + _current = cls._stack[-1] + del cls._stack[-1] + cls.set_as_current(_current, namespace) + + @classmethod def reset(cls, namespace): if cls._stack: cls.set_as_current(cls._stack[0], namespace) diff --git a/lib/sqlalchemy/testing/engines.py b/lib/sqlalchemy/testing/engines.py index 910af5876..280e6901e 100644 --- a/lib/sqlalchemy/testing/engines.py +++ b/lib/sqlalchemy/testing/engines.py @@ -238,10 +238,13 @@ def reconnecting_engine(url=None, options=None): return engine -def testing_engine(url=None, options=None): +def testing_engine(url=None, options=None, future=False): """Produce an engine configured by --options with optional overrides.""" - from sqlalchemy import create_engine + if future or config.db and config.db._is_future: + from sqlalchemy.future import create_engine + else: + from sqlalchemy import create_engine from sqlalchemy.engine.url import make_url if not options: diff --git a/lib/sqlalchemy/testing/fixtures.py b/lib/sqlalchemy/testing/fixtures.py index e5e6c42fc..26ae221b8 100644 --- a/lib/sqlalchemy/testing/fixtures.py +++ b/lib/sqlalchemy/testing/fixtures.py @@ -84,6 +84,29 @@ class TestBase(object): # engines.drop_all_tables(metadata, config.db) +class FutureEngineMixin(object): + @classmethod + def setup_class(cls): + super_ = super(FutureEngineMixin, cls) + if hasattr(super_, "setup_class"): + super_.setup_class() + + from ..future.engine import Engine + from sqlalchemy import testing + + config._current.push_engine(Engine._future_facade(config.db), testing) + + @classmethod + def teardown_class(cls): + from sqlalchemy import testing + + config._current.pop(testing) + + super_ = super(FutureEngineMixin, cls) + if hasattr(super_, "teardown_class"): + super_.teardown_class() + + class TablesTest(TestBase): # 'once', None diff --git a/lib/sqlalchemy/testing/suite/test_ddl.py b/lib/sqlalchemy/testing/suite/test_ddl.py index 1f49106fb..93706338c 100644 --- a/lib/sqlalchemy/testing/suite/test_ddl.py +++ b/lib/sqlalchemy/testing/suite/test_ddl.py @@ -90,4 +90,8 @@ class TableDDLTest(fixtures.TestBase): ) -__all__ = ("TableDDLTest",) +class FutureTableDDLTest(fixtures.FutureEngineMixin, TableDDLTest): + pass + + +__all__ = ("TableDDLTest", "FutureTableDDLTest") diff --git a/lib/sqlalchemy/testing/warnings.py b/lib/sqlalchemy/testing/warnings.py index 6b42c98cb..39cffbf15 100644 --- a/lib/sqlalchemy/testing/warnings.py +++ b/lib/sqlalchemy/testing/warnings.py @@ -34,6 +34,13 @@ def setup_filters(): # ignore 2.0 warnings unless we are explicitly testing for them warnings.filterwarnings("ignore", category=sa_exc.RemovedIn20Warning) + # ignore things that are deprecated *as of* 2.0 :) + warnings.filterwarnings( + "ignore", + category=sa_exc.SADeprecationWarning, + message=r".*\(deprecated since: 2.0\)$", + ) + try: import pytest except ImportError: |
