From: Mike Bayer Date: Sat, 12 Feb 2011 22:33:15 +0000 (-0500) Subject: - Added an explicit check for the case that the name X-Git-Tag: rel_0_7b1~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=de9ec22de972ec66f07db8b745108c6248bec6ad;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Added an explicit check for the case that the name 'metadata' is used for a column attribute on a declarative class. [ticket:2050] --- diff --git a/CHANGES b/CHANGES index f8fc77c372..641647d63c 100644 --- a/CHANGES +++ b/CHANGES @@ -331,6 +331,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 diff --git a/lib/sqlalchemy/ext/declarative.py b/lib/sqlalchemy/ext/declarative.py index 133bc84765..f80562b32a 100755 --- a/lib/sqlalchemy/ext/declarative.py +++ b/lib/sqlalchemy/ext/declarative.py @@ -820,7 +820,7 @@ from sqlalchemy.orm import synonym as _orm_synonym, mapper,\ from sqlalchemy.orm.interfaces import MapperProperty from sqlalchemy.orm.properties import RelationshipProperty, ColumnProperty, CompositeProperty 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 @@ -834,7 +834,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 @@ -890,7 +890,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: @@ -902,7 +902,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. ") @@ -916,7 +916,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 " @@ -964,6 +964,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 @@ -999,7 +1005,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, ...})" @@ -1019,7 +1025,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 ) @@ -1037,7 +1043,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 @@ -1060,7 +1066,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." ) @@ -1068,12 +1074,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]) @@ -1156,13 +1162,13 @@ class _GetColumns(object): mapper = class_mapper(self.cls, compile=False) if mapper: if not mapper.has_property(key): - raise exceptions.InvalidRequestError( + raise exc.InvalidRequestError( "Class %r does not have a mapped column named %r" % (self.cls, key)) prop = mapper.get_property(key) if 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) @@ -1202,7 +1208,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 " diff --git a/test/ext/test_declarative.py b/test/ext/test_declarative.py index cc743843f1..9d75333c85 100644 --- a/test/ext/test_declarative.py +++ b/test/ext/test_declarative.py @@ -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