]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- metadata.reflect() and reflection.Inspector()
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 23 Apr 2011 17:45:11 +0000 (10:45 -0700)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 23 Apr 2011 17:45:11 +0000 (10:45 -0700)
  had some reliance on GC to close connections
  which were internally procured, fixed this.
- added --zero-timeout option to nose fixture, sets pool_timeout to zero

CHANGES
lib/sqlalchemy/engine/reflection.py
lib/sqlalchemy/schema.py
test/bootstrap/config.py
test/bootstrap/noseplugin.py

diff --git a/CHANGES b/CHANGES
index 3c59cf3db0bda5e1f591a760a609841812f18a14..87c20d7a05e6f2c5db301f23c5d05f958a986e56 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -27,6 +27,10 @@ CHANGES
     connections are really closed when very 
     unusual DBAPI errors occur.
 
+  - metadata.reflect() and reflection.Inspector() 
+    had some reliance on GC to close connections
+    which were internally procured, fixed this.
+
   - Added explicit check for when Column .name
     is assigned as blank string [ticket:2140]
 
index 72eb27c4eb8288c505b55779ab9bf0e09231bdbf..ca436032535bcd484706aba94cb8f93d40bde5b8 100644 (file)
@@ -80,10 +80,6 @@ class Inspector(object):
         :meth:`Inspector.from_engine`
 
         """
-
-        # ensure initialized
-        bind.connect()
-
         # this might not be a connection, it could be an engine.
         self.bind = bind
 
@@ -92,6 +88,11 @@ class Inspector(object):
             self.engine = bind.engine
         else:
             self.engine = bind
+
+        if self.engine is bind:
+            # if engine, ensure initialized
+            bind.connect().close()
+
         self.dialect = self.engine.dialect
         self.info_cache = {}
 
index 72516acd6ee9cf9fe21de2046e724464c22f4c84..47fc7b08c9fe11e326d55eca7f4b306cc61ab71a 100644 (file)
@@ -2308,32 +2308,36 @@ class MetaData(SchemaItem):
         if schema is not None:
             reflect_opts['schema'] = schema
 
-        available = util.OrderedSet(bind.engine.table_names(schema,
+        try:
+            available = util.OrderedSet(bind.engine.table_names(schema,
                                                             connection=conn))
-        if views:
-            available.update(
-                bind.dialect.get_view_names(conn or bind, schema)
-            )
+            if views:
+                available.update(
+                    bind.dialect.get_view_names(conn or bind, schema)
+                )
 
-        current = set(self.tables.iterkeys())
+            current = set(self.tables.iterkeys())
 
-        if only is None:
-            load = [name for name in available if name not in current]
-        elif util.callable(only):
-            load = [name for name in available
+            if only is None:
+                load = [name for name in available if name not in current]
+            elif util.callable(only):
+                load = [name for name in available
                     if name not in current and only(name, self)]
-        else:
-            missing = [name for name in only if name not in available]
-            if missing:
-                s = schema and (" schema '%s'" % schema) or ''
-                raise exc.InvalidRequestError(
-                    'Could not reflect: requested table(s) not available '
-                    'in %s%s: (%s)' % 
-                    (bind.engine.url, s, ', '.join(missing)))
-            load = [name for name in only if name not in current]
-
-        for name in load:
-            Table(name, self, **reflect_opts)
+            else:
+                missing = [name for name in only if name not in available]
+                if missing:
+                    s = schema and (" schema '%s'" % schema) or ''
+                    raise exc.InvalidRequestError(
+                        'Could not reflect: requested table(s) not available '
+                        'in %s%s: (%s)' % 
+                        (bind.engine.url, s, ', '.join(missing)))
+                load = [name for name in only if name not in current]
+
+            for name in load:
+                Table(name, self, **reflect_opts)
+        finally:
+            if conn is not None:
+                conn.close()
 
     def append_ddl_listener(self, event_name, listener):
         """Append a DDL event listener to this ``MetaData``.
index 5bb301177dc53125423afc6df486e8b05f39b9a0..3905075bd84bc536b6712e1b686ae3827070c745 100644 (file)
@@ -53,6 +53,9 @@ def _list_dbs(*args):
 def _server_side_cursors(options, opt_str, value, parser):
     db_opts['server_side_cursors'] = True
 
+def _zero_timeout(options, opt_str, value, parser):
+    db_opts['pool_timeout'] = 0 
+
 def _engine_strategy(options, opt_str, value, parser):
     if value:
         db_opts['strategy'] = value
index a0e3b5ea367a2e78f06b4b8b5098ee7eff148d6c..156a18514fcb733aec547999e51f375a367227d6 100644 (file)
@@ -15,7 +15,7 @@ from test.bootstrap import config
 from test.bootstrap.config import (
     _create_testing_engine, _engine_pool, _engine_strategy, _engine_uri, _list_dbs, _log,
     _prep_testing_database, _require, _reverse_topological, _server_side_cursors,
-    _monkeypatch_cdecimal,
+    _monkeypatch_cdecimal, _zero_timeout,
     _set_table_options, base_config, db, db_label, db_url, file_config, post_configure, 
     pre_configure)
 
@@ -52,6 +52,8 @@ class NoseSQLAlchemy(Plugin):
             "MS-SQL)")
         opt("--mockpool", action="store_true", dest="mockpool",
             help="Use mock pool (asserts only one connection used)")
+        opt("--zero-timeout", action="callback", callback=_zero_timeout,
+            help="Set pool_timeout to zero, applies to QueuePool only")
         opt("--enginestrategy", action="callback", type="string",
             callback=_engine_strategy,
             help="Engine strategy (plain or threadlocal, defaults to plain)")