summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/schema.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2011-12-04 14:16:42 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2011-12-04 14:16:42 -0500
commit81945d7a0c60cc898541189d52564df2010871c1 (patch)
treec39ec598919f1c95d3126d67e19562de9309fef0 /lib/sqlalchemy/schema.py
parent133a0b2460f4c71692795ebbe52f9e521bb8782c (diff)
downloadsqlalchemy-81945d7a0c60cc898541189d52564df2010871c1.tar.gz
- [feature] The "extend_existing" flag on Table
now allows for the reflection process to take effect for a Table object that's already been defined; when autoload=True and extend_existing=True are both set, the full set of columns will be reflected from the Table which will then *overwrite* those columns already present, rather than no activity occurring. Columns that are present directly in the autoload run will be used as always, however. [ticket:1410]
Diffstat (limited to 'lib/sqlalchemy/schema.py')
-rw-r--r--lib/sqlalchemy/schema.py63
1 files changed, 45 insertions, 18 deletions
diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py
index 093a456e2..b5b057625 100644
--- a/lib/sqlalchemy/schema.py
+++ b/lib/sqlalchemy/schema.py
@@ -138,13 +138,34 @@ class Table(SchemaItem, expression.TableClause):
or Connection instance to be used for the table reflection. If
``None``, the underlying MetaData's bound connectable will be used.
- :param extend_existing: When ``True``, indicates that if this Table is already
+ :param extend_existing: When ``True``, indicates that if this :class:`.Table` is already
present in the given :class:`.MetaData`, apply further arguments within
the constructor to the existing :class:`.Table`.
- If extend_existing or keep_existing are not set, an error is
+ If ``extend_existing`` or ``keep_existing`` are not set, an error is
raised if additional table modifiers are specified when
the given :class:`.Table` is already present in the :class:`.MetaData`.
+
+ As of version 0.7.4, ``extend_existing`` will work in conjunction
+ with ``autoload=True`` to run a new reflection operation against
+ the database; new :class:`.Column` objects will be produced
+ from database metadata to replace those existing with the same
+ name, and additional :class:`.Column` objects not present
+ in the :class:`.Table` will be added.
+ As is always the case with ``autoload=True``, :class:`.Column`
+ objects can be specified in the same :class:`.Table` constructor,
+ which will take precedence. I.e.::
+
+ Table("mytable", metadata,
+ Column('y', Integer),
+ extend_existing=True,
+ autoload=True,
+ autoload_with=engine
+ )
+
+ The above will overwrite all columns within ``mytable`` which are present
+ in the database, except for ``y`` which will be used as is
+ from the above definition.
:param implicit_returning: True by default - indicates that
RETURNING can be used by default to fetch newly inserted primary key
@@ -329,27 +350,30 @@ class Table(SchemaItem, expression.TableClause):
# we do it after the table is in the singleton dictionary to support
# circular foreign keys
if autoload:
- if autoload_with:
- autoload_with.run_callable(
- autoload_with.dialect.reflecttable,
- self, include_columns
- )
- else:
- bind = _bind_or_error(metadata,
- msg="No engine is bound to this Table's MetaData. "
- "Pass an engine to the Table via "
- "autoload_with=<someengine>, "
- "or associate the MetaData with an engine via "
- "metadata.bind=<someengine>")
- bind.run_callable(
- bind.dialect.reflecttable,
- self, include_columns
- )
+ self._autoload(metadata, autoload_with, include_columns)
# 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):
+ if autoload_with:
+ autoload_with.run_callable(
+ autoload_with.dialect.reflecttable,
+ self, include_columns
+ )
+ else:
+ bind = _bind_or_error(metadata,
+ msg="No engine is bound to this Table's MetaData. "
+ "Pass an engine to the Table via "
+ "autoload_with=<someengine>, "
+ "or associate the MetaData with an engine via "
+ "metadata.bind=<someengine>")
+ bind.run_callable(
+ bind.dialect.reflecttable,
+ self, include_columns
+ )
+
@property
def _sorted_constraints(self):
"""Return the set of constraints as a list, sorted by creation order."""
@@ -378,6 +402,9 @@ class Table(SchemaItem, expression.TableClause):
if 'info' in kwargs:
self.info = kwargs.pop('info')
+ if autoload:
+ self._autoload(self.metadata, autoload_with, include_columns)
+
self._extra_kwargs(**kwargs)
self._init_items(*args)