summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2019-07-08 10:42:20 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2019-07-08 10:42:20 -0400
commit3238d953b42f67761dc3019bd27f2960ae2e525f (patch)
treef90962b324be393a1b9130b4de01040fea4a38d0
parentdd453e19a79785e91463cd2b37d12a1d0f36c03a (diff)
downloadsqlalchemy-3238d953b42f67761dc3019bd27f2960ae2e525f.tar.gz
Ensure .engine is part of Connectable interface, implement as descriptor
Fixed bug where using reflection function such as :meth:`.MetaData.reflect` with an :class:`.Engine` object that had execution options applied to it would fail, as the resulting :class:`.OptionEngine` proxy object failed to include a ``.engine`` attribute used within the reflection routines. Fixes: #4754 Change-Id: I6c342af5c6db6fe362b9d25f3f26d6859f62f87a
-rw-r--r--doc/build/changelog/unreleased_13/4754.rst8
-rw-r--r--lib/sqlalchemy/engine/base.py5
-rw-r--r--lib/sqlalchemy/engine/interfaces.py7
-rw-r--r--test/engine/test_execute.py4
-rw-r--r--test/engine/test_reflection.py5
5 files changed, 28 insertions, 1 deletions
diff --git a/doc/build/changelog/unreleased_13/4754.rst b/doc/build/changelog/unreleased_13/4754.rst
new file mode 100644
index 000000000..d8a3375cc
--- /dev/null
+++ b/doc/build/changelog/unreleased_13/4754.rst
@@ -0,0 +1,8 @@
+.. change::
+ :tags: bug, engine
+ :tickets: 4754
+
+ Fixed bug where using reflection function such as :meth:`.MetaData.reflect`
+ with an :class:`.Engine` object that had execution options applied to it
+ would fail, as the resulting :class:`.OptionEngine` proxy object failed to
+ include a ``.engine`` attribute used within the reflection routines.
diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py
index 7aee1a73b..07d1b8f89 100644
--- a/lib/sqlalchemy/engine/base.py
+++ b/lib/sqlalchemy/engine/base.py
@@ -1899,13 +1899,16 @@ class Engine(Connectable, log.Identified):
if logging_name:
self.logging_name = logging_name
self.echo = echo
- self.engine = self
log.instance_logger(self, echoflag=echo)
if proxy:
interfaces.ConnectionProxy._adapt_listener(self, proxy)
if execution_options:
self.update_execution_options(**execution_options)
+ @property
+ def engine(self):
+ return self
+
def update_execution_options(self, **opt):
r"""Update the default execution_options dictionary
of this :class:`.Engine`.
diff --git a/lib/sqlalchemy/engine/interfaces.py b/lib/sqlalchemy/engine/interfaces.py
index 4806e72a5..aadadb845 100644
--- a/lib/sqlalchemy/engine/interfaces.py
+++ b/lib/sqlalchemy/engine/interfaces.py
@@ -1117,6 +1117,13 @@ class Connectable(object):
"""
+ engine = None
+ """The :class:`.Engine` instance referred to by this :class:`.Connectable`.
+
+ May be ``self`` if this is already an :class:`.Engine`.
+
+ """
+
@util.deprecated(
"1.3",
"The :meth:`.Engine.contextual_connect` and "
diff --git a/test/engine/test_execute.py b/test/engine/test_execute.py
index 20c8ae659..335c3a487 100644
--- a/test/engine/test_execute.py
+++ b/test/engine/test_execute.py
@@ -635,10 +635,14 @@ class ExecuteTest(fixtures.TestBase):
options={"execution_options": {"base": "x1"}}
)
+ is_(eng.engine, eng)
+
eng1 = eng.execution_options(foo="b1")
+ is_(eng1.engine, eng1)
eng2 = eng.execution_options(foo="b2")
eng1a = eng1.execution_options(bar="a1")
eng2a = eng2.execution_options(foo="b3", bar="a2")
+ is_(eng2a.engine, eng2a)
eq_(eng._execution_options, {"base": "x1"})
eq_(eng1._execution_options, {"base": "x1", "foo": "b1"})
diff --git a/test/engine/test_reflection.py b/test/engine/test_reflection.py
index 3dc3a4461..1cabf8963 100644
--- a/test/engine/test_reflection.py
+++ b/test/engine/test_reflection.py
@@ -1198,6 +1198,11 @@ class ReflectionTest(fixtures.TestBase, ComparesTables):
def test_reflect_uses_bind_engine_reflect(self):
self._test_reflect_uses_bind(lambda e: MetaData().reflect(e))
+ def test_reflect_uses_bind_option_engine_reflect(self):
+ self._test_reflect_uses_bind(
+ lambda e: MetaData().reflect(e.execution_options(foo="bar"))
+ )
+
@testing.provide_metadata
def test_reflect_all(self):
existing = testing.db.table_names()