From: Mike Bayer Date: Sat, 23 Apr 2011 17:45:11 +0000 (-0700) Subject: - metadata.reflect() and reflection.Inspector() X-Git-Tag: rel_0_7_0~39 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d216298073ac6657728bdeb56598f3e5124e2d67;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - metadata.reflect() and reflection.Inspector() 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 --- diff --git a/CHANGES b/CHANGES index 3c59cf3db0..87c20d7a05 100644 --- 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] diff --git a/lib/sqlalchemy/engine/reflection.py b/lib/sqlalchemy/engine/reflection.py index 72eb27c4eb..ca43603253 100644 --- a/lib/sqlalchemy/engine/reflection.py +++ b/lib/sqlalchemy/engine/reflection.py @@ -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 = {} diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index 72516acd6e..47fc7b08c9 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -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``. diff --git a/test/bootstrap/config.py b/test/bootstrap/config.py index 5bb301177d..3905075bd8 100644 --- a/test/bootstrap/config.py +++ b/test/bootstrap/config.py @@ -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 diff --git a/test/bootstrap/noseplugin.py b/test/bootstrap/noseplugin.py index a0e3b5ea36..156a18514f 100644 --- a/test/bootstrap/noseplugin.py +++ b/test/bootstrap/noseplugin.py @@ -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)")