From: Mike Bayer Date: Sat, 2 Jan 2010 03:50:50 +0000 (+0000) Subject: - The copy() method on Column now supports uninitialized, X-Git-Tag: rel_0_6beta1~102 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d05a35daf82becc89a9493a178b76cc68363c4ae;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - The copy() method on Column now supports uninitialized, unnamed Column objects. This allows easy creation of declarative helpers which place common columns on multiple subclasses (merged from 0.5 with changes). --- diff --git a/CHANGES b/CHANGES index 1fd825d4c3..db902e79d8 100644 --- a/CHANGES +++ b/CHANGES @@ -791,6 +791,12 @@ CHANGES 0.5.8 ===== +- sql + - The copy() method on Column now supports uninitialized, + unnamed Column objects. This allows easy creation of + declarative helpers which place common columns on multiple + subclasses. + - postgresql - The extract() function, which was slightly improved in 0.5.7, needed a lot more work to generate the correct diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index 455582c878..ef9137ecd9 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -616,8 +616,8 @@ class Column(SchemaItem, expression.ColumnClause): name = kwargs.pop('name', None) type_ = kwargs.pop('type_', None) + args = list(args) if args: - args = list(args) if isinstance(args[0], basestring): if name is not None: raise exc.ArgumentError( @@ -794,10 +794,13 @@ class Column(SchemaItem, expression.ColumnClause): This is used in ``Table.tometadata``. """ + args = [c.copy(**kw) for c in self.constraints] + if self.table is None: + args += [c.copy(**kw) for c in self.foreign_keys] + return Column( - self.name, - self.type, - self.default, + name=self.name, + type_=self.type, key = self.key, primary_key = self.primary_key, nullable = self.nullable, @@ -808,7 +811,8 @@ class Column(SchemaItem, expression.ColumnClause): server_default=self.server_default, onupdate=self.onupdate, server_onupdate=self.server_onupdate, - *[c.copy(**kw) for c in self.constraints]) + *args + ) def _make_proxy(self, selectable, name=None): """Create a *proxy* for this column. @@ -925,7 +929,6 @@ class ForeignKey(SchemaItem): def copy(self, schema=None): """Produce a copy of this ForeignKey object.""" - return ForeignKey( self._get_colspec(schema=schema), use_alter=self.use_alter, @@ -1054,7 +1057,6 @@ class ForeignKey(SchemaItem): return raise exc.InvalidRequestError("This ForeignKey already has a parent !") self.parent = column - self.parent.foreign_keys.add(self) self.parent._on_table_attach(self._set_table) diff --git a/test/engine/test_metadata.py b/test/engine/test_metadata.py index e2179da09e..6e846096bd 100644 --- a/test/engine/test_metadata.py +++ b/test/engine/test_metadata.py @@ -36,6 +36,24 @@ class MetaDataTest(TestBase, ComparesTables): assert t3 not in metadata assert t4 not in metadata + def test_uninitialized_column_copy(self): + for col in [ + Column('foo', String(), nullable=False), + Column(Integer(), primary_key=True), + Column('bar', Integer(), Sequence('foo_seq'), primary_key=True, key='bar'), + Column(Integer(), ForeignKey('bat.blah')), + Column('bar', Integer(), ForeignKey('bat.blah'), primary_key=True, key='bar'), + ]: + c2 = col.copy() + for attr in ('name', 'type', 'nullable', 'primary_key', 'key'): + eq_(getattr(col, attr), getattr(c2, attr)) + eq_(len(col.foreign_keys), len(c2.foreign_keys)) + if col.default: + eq_(c2.default.name, 'foo_seq') + for a1, a2 in zip(col.foreign_keys, c2.foreign_keys): + assert a1 is not a2 + eq_(a2._colspec, 'bat.blah') + def test_dupe_tables(self): metadata = MetaData() t1 = Table('table1', metadata, Column('col1', Integer, primary_key=True),