summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/schema.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2016-11-23 09:14:02 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2016-11-23 10:31:56 -0500
commit55ad10370f9eb50795e136aac595193168982e92 (patch)
tree2571e7b7d844dec8cb22cf475188e3ec65cb3184 /lib/sqlalchemy/sql/schema.py
parent868e98bf407175b016e9e5cbc95bcf0cc859362a (diff)
downloadsqlalchemy-55ad10370f9eb50795e136aac595193168982e92.tar.gz
Add _extend_on deduplicating set for metadata.reflect()
The "extend_existing" option of :class:`.Table` reflection would cause indexes and constraints to be doubled up in the case that the parameter were used with :meth:`.MetaData.reflect` (as the automap extension does) due to tables being reflected both within the foreign key path as well as directly. A new de-duplicating set is passed through within the :meth:`.MetaData.reflect` sequence to prevent double reflection in this way. Change-Id: Ibf6650c1e76a44ccbe15765fd79df2fa53d6bac7 Fixes: #3861
Diffstat (limited to 'lib/sqlalchemy/sql/schema.py')
-rw-r--r--lib/sqlalchemy/sql/schema.py24
1 files changed, 18 insertions, 6 deletions
diff --git a/lib/sqlalchemy/sql/schema.py b/lib/sqlalchemy/sql/schema.py
index 27ef9e01b..5c48e5bbb 100644
--- a/lib/sqlalchemy/sql/schema.py
+++ b/lib/sqlalchemy/sql/schema.py
@@ -485,6 +485,8 @@ class Table(DialectKWArgs, SchemaItem, TableClause):
autoload = kwargs.pop('autoload', autoload_with is not None)
# this argument is only used with _init_existing()
kwargs.pop('autoload_replace', True)
+ _extend_on = kwargs.pop("_extend_on", None)
+
include_columns = kwargs.pop('include_columns', None)
self.implicit_returning = kwargs.pop('implicit_returning', True)
@@ -504,19 +506,22 @@ class Table(DialectKWArgs, SchemaItem, TableClause):
# we do it after the table is in the singleton dictionary to support
# circular foreign keys
if autoload:
- self._autoload(metadata, autoload_with, include_columns)
+ self._autoload(
+ metadata, autoload_with,
+ include_columns, _extend_on=_extend_on)
# initialize all the column, etc. objects. done after reflection to
# allow user-overrides
self._init_items(*args)
def _autoload(self, metadata, autoload_with, include_columns,
- exclude_columns=()):
+ exclude_columns=(), _extend_on=None):
if autoload_with:
autoload_with.run_callable(
autoload_with.dialect.reflecttable,
- self, include_columns, exclude_columns
+ self, include_columns, exclude_columns,
+ _extend_on=_extend_on
)
else:
bind = _bind_or_error(
@@ -528,7 +533,8 @@ class Table(DialectKWArgs, SchemaItem, TableClause):
"metadata.bind=<someengine>")
bind.run_callable(
bind.dialect.reflecttable,
- self, include_columns, exclude_columns
+ self, include_columns, exclude_columns,
+ _extend_on=_extend_on
)
@property
@@ -557,6 +563,8 @@ class Table(DialectKWArgs, SchemaItem, TableClause):
autoload = kwargs.pop('autoload', autoload_with is not None)
autoload_replace = kwargs.pop('autoload_replace', True)
schema = kwargs.pop('schema', None)
+ _extend_on = kwargs.pop('_extend_on', None)
+
if schema and schema != self.schema:
raise exc.ArgumentError(
"Can't change schema of existing table from '%s' to '%s'",
@@ -579,12 +587,15 @@ class Table(DialectKWArgs, SchemaItem, TableClause):
if autoload:
if not autoload_replace:
+ # don't replace columns already present.
+ # we'd like to do this for constraints also however we don't
+ # have simple de-duping for unnamed constraints.
exclude_columns = [c.name for c in self.c]
else:
exclude_columns = ()
self._autoload(
self.metadata, autoload_with,
- include_columns, exclude_columns)
+ include_columns, exclude_columns, _extend_on=_extend_on)
self._extra_kwargs(**kwargs)
self._init_items(*args)
@@ -3758,7 +3769,8 @@ class MetaData(SchemaItem):
'autoload': True,
'autoload_with': conn,
'extend_existing': extend_existing,
- 'autoload_replace': autoload_replace
+ 'autoload_replace': autoload_replace,
+ '_extend_on': set()
}
reflect_opts.update(dialect_kwargs)