]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Don't import provision.py unconditionally
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 3 Mar 2020 21:03:39 +0000 (16:03 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 3 Mar 2020 21:06:06 +0000 (16:06 -0500)
Removed the imports for provision.py from each dialect
and instead added a call in the central provision.py to
a new dialect level method load_provisioning().  The
provisioning registry works in the same way, so an existing
dialect that is using the provision.py system right now
by importing it as part of the package will still continue to
function.  However, to avoid pulling in the testing package when
the dialect is used in a non-testing context, the new hook may be
used.   Also removed a module-level dependency
of the testing framework on the orm package.

Revised an internal change to the test system added as a result of
:ticket:`5085` where a testing-related module per dialect would be loaded
unconditionally upon making use of that dialect, pulling in SQLAlchemy's
testing framework as well as the ORM into the module import space.   This
would only impact initial startup time and memory to a modest extent,
however it's best that these additional modules aren't reverse-dependent on
straight Core usage.

Fixes: #5180
Change-Id: I6355601da5f6f44d85a2bbc3acb5928559942b9c

doc/build/changelog/unreleased_13/5180.rst [new file with mode: 0644]
lib/sqlalchemy/dialects/mssql/__init__.py
lib/sqlalchemy/dialects/mysql/__init__.py
lib/sqlalchemy/dialects/oracle/__init__.py
lib/sqlalchemy/dialects/postgresql/__init__.py
lib/sqlalchemy/dialects/sqlite/__init__.py
lib/sqlalchemy/engine/default.py
lib/sqlalchemy/engine/interfaces.py
lib/sqlalchemy/orm/query.py
lib/sqlalchemy/testing/assertions.py
lib/sqlalchemy/testing/provision.py

diff --git a/doc/build/changelog/unreleased_13/5180.rst b/doc/build/changelog/unreleased_13/5180.rst
new file mode 100644 (file)
index 0000000..85ac9a6
--- /dev/null
@@ -0,0 +1,11 @@
+.. change::
+    :tags: bug, performance
+    :tickets: 5180
+
+    Revised an internal change to the test system added as a result of
+    :ticket:`5085` where a testing-related module per dialect would be loaded
+    unconditionally upon making use of that dialect, pulling in SQLAlchemy's
+    testing framework as well as the ORM into the module import space.   This
+    would only impact initial startup time and memory to a modest extent,
+    however it's best that these additional modules aren't reverse-dependent on
+    straight Core usage.
index cbee8c0dc24109c7cb631fef1ba5257725fb627f..67830affe308035448b53e0fd44be7e166f4a9fb 100644 (file)
@@ -8,7 +8,6 @@
 from . import adodbapi  # noqa
 from . import base  # noqa
 from . import mxodbc  # noqa
-from . import provision  # noqa
 from . import pymssql  # noqa
 from . import pyodbc  # noqa
 from .base import BIGINT
index 12eb673a7398be2d967ea2bc8463c4c4a5a52fa3..f1f1cce371a5c509068e14bfd1064b3751dc4702 100644 (file)
@@ -11,7 +11,6 @@ from . import gaerdbms  # noqa
 from . import mysqlconnector  # noqa
 from . import mysqldb  # noqa
 from . import oursql  # noqa
-from . import provision  # noqa
 from . import pymysql  # noqa
 from . import pyodbc  # noqa
 from .base import BIGINT
index 90157bd67bf4845795169f590a63fbe87542a6c0..a4dee02ff93e40c978daccc2d9a0e7a2c748df2b 100644 (file)
@@ -7,7 +7,6 @@
 
 from . import base  # noqa
 from . import cx_oracle  # noqa
-from . import provision  # noqa
 from .base import BFILE
 from .base import BINARY_DOUBLE
 from .base import BINARY_FLOAT
index c6482222d2e8445dba6dfd568b11313d0608622a..06d22872a980838b554fc1420f213f390f236d7b 100644 (file)
@@ -7,7 +7,6 @@
 
 from . import base
 from . import pg8000  # noqa
-from . import provision  # noqa
 from . import psycopg2  # noqa
 from . import psycopg2cffi  # noqa
 from . import pygresql  # noqa
index c35cb9251cca1aa406a7eefefd03a0981195250e..142131f631bddeed30951f5caca9a58d763414ff 100644 (file)
@@ -6,7 +6,6 @@
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
 from . import base  # noqa
-from . import provision  # noqa
 from . import pysqlcipher  # noqa
 from . import pysqlite  # noqa
 from .base import BLOB
index 28a59e6601c0014c6209bcbbc14460691459714d..8775a88136002a44b41072509d5b462f1e1e0b8a 100644 (file)
@@ -293,6 +293,14 @@ class DefaultDialect(interfaces.Dialect):
     def get_pool_class(cls, url):
         return getattr(cls, "poolclass", pool.QueuePool)
 
+    @classmethod
+    def load_provisioning(cls):
+        package = ".".join(cls.__module__.split(".")[0:-1])
+        try:
+            __import__(package + ".provision")
+        except ImportError:
+            pass
+
     def initialize(self, connection):
         try:
             self.server_version_info = self._get_server_version_info(
index 04e572c2d25e57ee912e9b9ce24bf5a2a7a44e67..84def853f2f237c4316fd39ff23fe5de184ea37c 100644 (file)
@@ -865,6 +865,35 @@ class Dialect(object):
         """
         return cls
 
+    @classmethod
+    def load_provisioning(cls):
+        """set up the provision.py module for this dialect.
+
+        For dialects that include a provision.py module that sets up
+        provisioning followers, this method should initiate that process.
+
+        A typical implementation would be::
+
+            @classmethod
+            def load_provisioning(cls):
+                __import__("mydialect.provision")
+
+        The default method assumes a module named ``provision.py`` inside
+        the owning package of the current dialect, based on the ``__module__``
+        attribute::
+
+            @classmethod
+            def load_provisioning(cls):
+                package = ".".join(cls.__module__.split(".")[0:-1])
+                try:
+                    __import__(package + ".provision")
+                except ImportError:
+                    pass
+
+        .. versionadded:: 1.3.14
+
+        """
+
     @classmethod
     def engine_created(cls, engine):
         """A convenience hook called before returning the final :class:`.Engine`.
index e29e6eeeeb03a480fd12315a0f5813aa9f75e0d1..830cede93d5bf551fc09e1e2c06201e1d4de9021 100644 (file)
@@ -59,7 +59,6 @@ from ..sql.base import Generative
 from ..sql.selectable import ForUpdateArg
 from ..util import collections_abc
 
-
 __all__ = ["Query", "QueryContext", "aliased"]
 
 
index c97202516bf083a58b08b9e0955b7e890b9b012e..07a70bf6cd30bdbf9d72d307dc9ae160ea4b2c0f 100644 (file)
@@ -19,7 +19,6 @@ from . import mock
 from .exclusions import db_spec
 from .util import fail
 from .. import exc as sa_exc
-from .. import orm
 from .. import schema
 from .. import types as sqltypes
 from .. import util
@@ -386,6 +385,8 @@ class AssertsCompiledSQL(object):
         if render_postcompile:
             compile_kwargs["render_postcompile"] = True
 
+        from sqlalchemy import orm
+
         if isinstance(clause, orm.Query):
             context = clause._compile_context()
             context.statement.use_labels = True
index 6e2e1ccf50f76933492e1da3a6c7c771724154be..543d91a533f2e247d944afed870ea9a99741fc2c 100644 (file)
@@ -6,7 +6,6 @@ from . import engines
 from ..engine import url as sa_url
 from ..util import compat
 
-
 log = logging.getLogger(__name__)
 
 FOLLOWER_IDENT = None
@@ -51,7 +50,9 @@ def setup_config(db_url, options, file_config, follower_ident):
     # load the dialect, which should also have it set up its provision
     # hooks
 
-    sa_url.make_url(db_url).get_dialect()
+    dialect = sa_url.make_url(db_url).get_dialect()
+    dialect.load_provisioning()
+
     if follower_ident:
         db_url = follower_url_from_main(db_url, follower_ident)
     db_opts = {}