if isinstance(ret, (Column, MapperProperty)) and \
ret.doc is None:
ret.doc = obj.__doc__
+ # here, the attribute is some other kind of property that
+ # we assume is not part of the declarative mapping.
+ # however, check for some more common mistakes
+ else:
+ self._warn_for_decl_attributes(base, name, obj)
if inherited_table_args and not tablename:
table_args = None
self.tablename = tablename
self.mapper_args_fn = mapper_args_fn
+ def _warn_for_decl_attributes(self, cls, key, c):
+ if isinstance(c, expression.ColumnClause):
+ util.warn(
+ "Attribute '%s' on class %s appears to be a non-schema "
+ "'sqlalchemy.sql.column()' "
+ "object; this won't be part of the declarative mapping" %
+ (key, cls))
+
def _produce_column_copies(self, base):
cls = self.cls
dict_ = self.dict_
# and place the evaluated value onto the class.
if not k.startswith('__'):
dict_.pop(k)
+ self._warn_for_decl_attributes(cls, k, value)
if not late_mapped:
setattr(cls, k, value)
continue
from sqlalchemy.testing import eq_, assert_raises, \
assert_raises_message, expect_warnings, is_
+from sqlalchemy.testing import assertions
from sqlalchemy.ext import declarative as decl
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy import exc
assert class_mapper(Bar).get_property('some_data').columns[0] \
is t.c.data
+ def test_lower_case_c_column_warning(self):
+ with assertions.expect_warnings(
+ r"Attribute 'x' on class <class .*Foo.* appears to be a "
+ r"non-schema 'sqlalchemy.sql.column\(\)' object; ",
+ ):
+ class Foo(Base):
+ __tablename__ = 'foo'
+
+ id = Column(Integer, primary_key=True)
+ x = sa.sql.expression.column(Integer)
+ y = Column(Integer)
+
+ class MyMixin(object):
+ x = sa.sql.expression.column(Integer)
+ y = Column(Integer)
+
+ with assertions.expect_warnings(
+ r"Attribute 'x' on class <class .*MyMixin.* appears to be a "
+ r"non-schema 'sqlalchemy.sql.column\(\)' object; ",
+ ):
+ class Foo2(MyMixin, Base):
+ __tablename__ = 'foo2'
+
+ id = Column(Integer, primary_key=True)
+
+ with assertions.expect_warnings(
+ r"Attribute 'x' on class <class .*Foo3.* appears to be a "
+ r"non-schema 'sqlalchemy.sql.column\(\)' object; ",
+ ):
+ class Foo3(Base):
+ __tablename__ = 'foo3'
+
+ id = Column(Integer, primary_key=True)
+
+ @declared_attr
+ def x(cls):
+ return sa.sql.expression.column(Integer)
+
+ y = Column(Integer)
+
+ with assertions.expect_warnings(
+ r"Attribute 'x' on class <class .*Foo4.* appears to be a "
+ r"non-schema 'sqlalchemy.sql.column\(\)' object; ",
+ ):
+ class MyMixin2(object):
+ @declared_attr
+ def x(cls):
+ return sa.sql.expression.column(Integer)
+
+ y = Column(Integer)
+
+ class Foo4(MyMixin2, Base):
+ __tablename__ = 'foo4'
+
+ id = Column(Integer, primary_key=True)
+
def test_column_named_twice(self):
def go():
class Foo(Base):