diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2016-11-23 09:14:02 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2016-11-23 10:31:56 -0500 |
| commit | 55ad10370f9eb50795e136aac595193168982e92 (patch) | |
| tree | 2571e7b7d844dec8cb22cf475188e3ec65cb3184 /lib/sqlalchemy/sql/schema.py | |
| parent | 868e98bf407175b016e9e5cbc95bcf0cc859362a (diff) | |
| download | sqlalchemy-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.py | 24 |
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) |
