]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Added an explicit check for the case that the name
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 12 Feb 2011 22:35:29 +0000 (17:35 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 12 Feb 2011 22:35:29 +0000 (17:35 -0500)
    'metadata' is used for a column attribute on a
    declarative class. [ticket:2050]

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

diff --git a/CHANGES b/CHANGES
index d35ef809daba898ed594f463a8a0ae74f1d24ec8..4fb637271a0b02a5aba754d6e1302260e509da7a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -63,6 +63,12 @@ CHANGES
   - oursql dialect accepts the same "ssl" arguments in 
     create_engine() as that of MySQLdb.  [ticket:2047]
 
+- declarative
+  - Added an explicit check for the case that the name
+    'metadata' is used for a column attribute on a 
+    declarative class. [ticket:2050]
+
+
 0.6.6
 =====
 - orm
index d78f89ac7b3126dcc004b44f26f3bcb5c070a5f6..651729058208dee517943099f3959e636850d773 100755 (executable)
@@ -862,7 +862,7 @@ from sqlalchemy.orm import synonym as _orm_synonym, mapper,\
 from sqlalchemy.orm.interfaces import MapperProperty
 from sqlalchemy.orm.properties import RelationshipProperty, ColumnProperty
 from sqlalchemy.orm.util import _is_mapped_class
-from sqlalchemy import util, exceptions
+from sqlalchemy import util, exc
 from sqlalchemy.sql import util as sql_util, expression
 
 
@@ -876,7 +876,7 @@ def instrument_declarative(cls, registry, metadata):
 
     """
     if '_decl_class_registry' in cls.__dict__:
-        raise exceptions.InvalidRequestError(
+        raise exc.InvalidRequestError(
                             "Class %r already has been "
                             "instrumented declaratively" % cls)
     cls._decl_class_registry = registry
@@ -932,7 +932,7 @@ def _as_declarative(cls, classname, dict_):
                                     ):
                     table_args = cls.__table_args__
                     if not isinstance(table_args, (tuple, dict, type(None))):
-                        raise exceptions.ArgumentError(
+                        raise exc.ArgumentError(
                                 "__table_args__ value must be a tuple, "
                                 "dict, or None")
                     if base is not cls:
@@ -944,7 +944,7 @@ def _as_declarative(cls, classname, dict_):
 
                 if isinstance(obj, Column):
                     if obj.foreign_keys:
-                        raise exceptions.InvalidRequestError(
+                        raise exc.InvalidRequestError(
                         "Columns with foreign keys to other columns "
                         "must be declared as @classproperty callables "
                         "on declarative mixin classes. ")
@@ -958,7 +958,7 @@ def _as_declarative(cls, classname, dict_):
                         column_copies[obj]._creation_order = \
                                 obj._creation_order
                 elif isinstance(obj, MapperProperty):
-                    raise exceptions.InvalidRequestError(
+                    raise exc.InvalidRequestError(
                         "Mapper properties (i.e. deferred,"
                         "column_property(), relationship(), etc.) must "
                         "be declared as @classproperty callables "
@@ -1006,6 +1006,12 @@ def _as_declarative(cls, classname, dict_):
             continue
         if not isinstance(value, (Column, MapperProperty)):
             continue
+        if k == 'metadata':
+            raise exc.InvalidRequestError(
+                "Attribute name 'metadata' is reserved "
+                "for the MetaData instance when using a "
+                "declarative base class."
+            )
         prop = _deferred_relationship(cls, value)
         our_stuff[k] = prop
 
@@ -1041,7 +1047,7 @@ def _as_declarative(cls, classname, dict_):
                 args = table_args[0:-1]
                 table_kw = table_args[-1]
                 if len(table_args) < 2 or not isinstance(table_kw, dict):
-                    raise exceptions.ArgumentError(
+                    raise exc.ArgumentError(
                         "Tuple form of __table_args__ is "
                         "(arg1, arg2, arg3, ..., {'kw1':val1, "
                         "'kw2':val2, ...})"
@@ -1061,7 +1067,7 @@ def _as_declarative(cls, classname, dict_):
         if cols:
             for c in cols:
                 if not table.c.contains_column(c):
-                    raise exceptions.ArgumentError(
+                    raise exc.ArgumentError(
                         "Can't add additional column %r when "
                         "specifying __table__" % c.key
                     )
@@ -1079,7 +1085,7 @@ def _as_declarative(cls, classname, dict_):
         mapper_cls = mapper
 
     if table is None and 'inherits' not in mapper_args:
-        raise exceptions.InvalidRequestError(
+        raise exc.InvalidRequestError(
             "Class %r does not have a __table__ or __tablename__ "
             "specified and does not inherit from an existing "
             "table-mapped class." % cls
@@ -1102,7 +1108,7 @@ def _as_declarative(cls, classname, dict_):
             # single table inheritance.
             # ensure no table args
             if table_args:
-                raise exceptions.ArgumentError(
+                raise exc.ArgumentError(
                     "Can't place __table_args__ on an inherited class "
                     "with no table."
                     )
@@ -1110,12 +1116,12 @@ def _as_declarative(cls, classname, dict_):
             # add any columns declared here to the inherited table.
             for c in cols:
                 if c.primary_key:
-                    raise exceptions.ArgumentError(
+                    raise exc.ArgumentError(
                         "Can't place primary key columns on an inherited "
                         "class with no table."
                         )
                 if c.name in inherited_table.c:
-                    raise exceptions.ArgumentError(
+                    raise exc.ArgumentError(
                         "Column '%s' on class %s conflicts with "
                         "existing column '%s'" % 
                         (c, cls, inherited_table.c[c.name])
@@ -1199,11 +1205,11 @@ class _GetColumns(object):
         if mapper:
             prop = mapper.get_property(key, raiseerr=False)
             if prop is None:
-                raise exceptions.InvalidRequestError(
+                raise exc.InvalidRequestError(
                             "Class %r does not have a mapped column named %r"
                             % (self.cls, key))
             elif not isinstance(prop, ColumnProperty):
-                raise exceptions.InvalidRequestError(
+                raise exc.InvalidRequestError(
                             "Property %r is not an instance of"
                             " ColumnProperty (i.e. does not correspond"
                             " directly to a Column)." % key)
@@ -1232,7 +1238,7 @@ def _deferred_relationship(cls, prop):
                 else:
                     return x
             except NameError, n:
-                raise exceptions.InvalidRequestError(
+                raise exc.InvalidRequestError(
                     "When initializing mapper %s, expression %r failed to "
                     "locate a name (%r). If this is a class name, consider "
                     "adding this relationship() to the %r class after "
index 37d92812925973c15ad099aca61bbe94ec376377..743831d251f6c6d743848c9a1baa98778daa4b28 100644 (file)
@@ -126,6 +126,27 @@ class DeclarativeTest(DeclarativeTestBase):
 
         decl.instrument_declarative(User,{},Base.metadata)
 
+    def test_reserved_identifiers(self):
+        def go1():
+            class User1(Base):
+                __tablename__ = 'user1'
+                id = Column(Integer, primary_key=True)
+                metadata = Column(Integer)
+
+        def go2():
+            class User2(Base):
+                __tablename__ = 'user2'
+                id = Column(Integer, primary_key=True)
+                metadata = relationship("Address")
+
+        for go in (go1, go2):
+            assert_raises_message(
+                exc.InvalidRequestError,
+                "Attribute name 'metadata' is reserved "
+                "for the MetaData instance when using a "
+                "declarative base class.",
+                go
+            )
 
     def test_undefer_column_name(self):
         # TODO: not sure if there was an explicit