]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- a mixin class can now define a column that matches
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 19 Jun 2010 17:25:37 +0000 (13:25 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 19 Jun 2010 17:25:37 +0000 (13:25 -0400)
one which is present on a __table__ defined on a
subclass.  It cannot, however, define one that is
not present in the __table__, and the error message
here now works.  [ticket:1821]

CHANGES
lib/sqlalchemy/ext/declarative.py
test/ext/test_declarative.py

diff --git a/CHANGES b/CHANGES
index 8d1b3207db63df56d11e2065dbc22df7214ff7f9..f41bac381dd51857f1bbbf100b5ab8f626fd919b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -87,6 +87,13 @@ CHANGES
   - Fixed incorrect signature in do_execute(), error 
     introduced in 0.6.1. [ticket:1823]
 
+- declarative
+   - a mixin class can now define a column that matches
+     one which is present on a __table__ defined on a 
+     subclass.  It cannot, however, define one that is 
+     not present in the __table__, and the error message
+     here now works.  [ticket:1821]
+     
 - documentation
   - Added documentation for the Inspector. [ticket:1820]
   
index 8a28bb07ccf1386c3b284998bf814d6059d692ce..385e0a309d9e2eb0fb5f7e4c5c06db0c1a1f1522 100755 (executable)
@@ -645,7 +645,7 @@ def _as_declarative(cls, classname, dict_):
     mapper_args ={}
     table_args = inherited_table_args = None
     tablename = None
-    parent_columns = None
+    parent_columns = ()
     
     for base in cls.__mro__:
         if _is_mapped_class(base):
@@ -670,7 +670,9 @@ def _as_declarative(cls, classname, dict_):
                                 "Columns with foreign keys to other columns "
                                 "are not allowed on declarative mixins at this time."
                             )
-                        if name not in dict_:
+                        if name not in dict_ and not (
+                                '__table__' in dict_ and name in dict_['__table__'].c
+                                ):
                             potential_columns[name]=column_copies[obj]=obj.copy()
                     elif isinstance(obj, RelationshipProperty):
                         raise exceptions.InvalidRequestError(
index 87793658dfd120aebd7b0ea73da3619432bc9ebc..04ce401e581116299088f72983c6d2bcc87f891f 100644 (file)
@@ -2365,3 +2365,60 @@ class DeclarativeMixinTest(DeclarativeTestBase):
             __mapper_args__ = dict(polymorphic_identity='specific')
             
         eq_(BaseType.__table__.c.keys(),['type', 'id', 'timestamp'])
+
+    def test_table_in_model_and_same_column_in_mixin(self):
+        
+        class ColumnMixin:
+            data = Column(Integer)
+        
+        class Model(Base, ColumnMixin):
+            __table__ = Table(
+                'foo',
+                Base.metadata,
+                Column('data', Integer),
+                Column('id', Integer, primary_key=True) 
+                )
+        
+        model_col = Model.__table__.c.data
+        mixin_col = ColumnMixin.data
+        assert model_col is not mixin_col
+        eq_(model_col.name, 'data')
+        assert model_col.type.__class__ is mixin_col.type.__class__
+    
+    def test_table_in_model_and_different_named_column_in_mixin(self):
+        
+        class ColumnMixin:
+            tada = Column(Integer)
+        
+        def go():
+            class Model(Base, ColumnMixin):
+                __table__ = Table(
+                    'foo',
+                    Base.metadata,
+                    Column('data', Integer),
+                    Column('id', Integer, primary_key=True)
+                    )
+        
+        assert_raises_message(
+            sa.exc.ArgumentError,
+            "Can't add additional column 'tada' when specifying __table__",
+            go)
+    
+    def test_table_in_model_overrides_different_typed_column_in_mixin(self):
+        
+        class ColumnMixin:
+            data = Column(String)
+        
+        class Model(Base, ColumnMixin):
+            __table__ = Table(
+                'foo',
+                Base.metadata,
+                Column('data', Integer),
+                Column('id', Integer, primary_key=True)
+                )
+
+        model_col = Model.__table__.c.data
+        mixin_col = ColumnMixin.data
+        assert model_col is not mixin_col
+        eq_(model_col.name, 'data')
+        assert model_col.type.__class__ is Integer