From: Mike Bayer Date: Sat, 18 Sep 2010 15:40:25 +0000 (-0400) Subject: - use "key in dict" rather than KeyError if the usual case X-Git-Tag: rel_0_6_5~61 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=611fb77186d7379a4ab8378326cbbb380c6e8cd6;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - use "key in dict" rather than KeyError if the usual case is that the key is not present. - don't need to uniquify Index schemes, just don't copy Indexes that were known to be generated from the index=True flag - user facing changes go in CHANGES - Table.c allows string lookup --- diff --git a/CHANGES b/CHANGES index abcd25ef04..1cf7a39f62 100644 --- a/CHANGES +++ b/CHANGES @@ -84,6 +84,14 @@ CHANGES of the query only, instead of repeatedly. May make some more adjustments to this. +- sql + - Table.tometadata() now copies Index objects associated + with the Table as well. + + - Table.tometadata() issues a warning if the given Table + is already present in the target MetaData - the existing + Table object is returned. + - engine - Fixed a regression in 0.6.4 whereby the change that diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index 99e8c2a8c3..4b7916e98f 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -467,43 +467,34 @@ class Table(SchemaItem, expression.TableClause): """ - try: - if schema is RETAIN_SCHEMA: - schema = self.schema - key = _get_table_key(self.name, schema) - result = metadata.tables[key] - util.warn('tometadata will raise an exception ' - 'when a table already exists in the ' - 'target metadata in SQLAlchemy 0.7') - return result - except KeyError: - args = [] - for c in self.columns: - args.append(c.copy(schema=schema)) - for c in self.constraints: - args.append(c.copy(schema=schema)) - table = Table( - self.name, metadata, schema=schema, - *args, **self.kwargs - ) - copied_already = set() - for i in table.indexes: - entry = [i.name,i.unique] - entry.extend(sorted(i.kwargs.items())) - entry.extend(i.columns.keys()) - copied_already.add(tuple(entry)) - for i in self.indexes: - cols = i.columns.keys() - entry = [i.name,i.unique] - entry.extend(sorted(i.kwargs.items())) - entry.extend(cols) - if tuple(entry) not in copied_already: - kwargs = dict(i.kwargs) - kwargs['unique']=i.unique - Index(i.name, - *[getattr(table.c,col) for col in cols], - **kwargs) - return table + if schema is RETAIN_SCHEMA: + schema = self.schema + key = _get_table_key(self.name, schema) + if key in metadata.tables: + util.warn("Table '%s' already exists within the given " + "MetaData - not copying." % self.description) + return metadata.tables[key] + + args = [] + for c in self.columns: + args.append(c.copy(schema=schema)) + for c in self.constraints: + args.append(c.copy(schema=schema)) + table = Table( + self.name, metadata, schema=schema, + *args, **self.kwargs + ) + for index in self.indexes: + # skip indexes that would be generated + # by the 'index' flag on Column + if len(index.columns) == 1 and \ + list(index.columns)[0].index: + continue + Index(index.name, + unique=index.unique, + *[table.c[col] for col in index.columns.keys()], + **index.kwargs) + return table class Column(SchemaItem, expression.ColumnClause): """Represents a column in a database table.""" diff --git a/test/engine/test_metadata.py b/test/engine/test_metadata.py index 4df7205507..528d56244f 100644 --- a/test/engine/test_metadata.py +++ b/test/engine/test_metadata.py @@ -276,19 +276,16 @@ class MetaDataTest(TestBase, ComparesTables): table_c = table.tometadata(meta2) def _get_key(i): - entry = [i.name,i.unique] - entry.extend(sorted(i.kwargs.items())) - entry.extend(i.columns.keys()) - return entry - - table_indexes = [_get_key(i) for i in table.indexes] - table_indexes.sort() - table_c_indexes = [_get_key(i) for i in table_c.indexes] - table_c_indexes.sort() - - eq_(table_indexes,table_c_indexes) - - @emits_warning('tometadata.*') + return [i.name,i.unique] + \ + sorted(i.kwargs.items()) + \ + i.columns.keys() + + eq_( + sorted([_get_key(i) for i in table.indexes]), + sorted([_get_key(i) for i in table_c.indexes]) + ) + + @emits_warning("Table '.+' already exists within the given MetaData") def test_tometadata_already_there(self): meta1 = MetaData()