From: Mike Bayer Date: Sat, 25 Jul 2009 20:43:11 +0000 (+0000) Subject: - Declarative will raise an informative exception if X-Git-Tag: rel_0_5_6~29 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a510e9f23abe0df6eaa781094b191eb3178b2c7d;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Declarative will raise an informative exception if __table_args__ is passed as a tuple with no dict argument. Improved documentation. [ticket:1468] --- diff --git a/CHANGES b/CHANGES index eebdad0e9a..b13600cad8 100644 --- a/CHANGES +++ b/CHANGES @@ -46,7 +46,11 @@ CHANGES pickleable. A user-defined proxy_factory however is still not pickleable unless it defines __getstate__ and __setstate__. [ticket:1446] - + + - Declarative will raise an informative exception if + __table_args__ is passed as a tuple with no dict argument. + Improved documentation. [ticket:1468] + 0.5.5 ======= - general diff --git a/lib/sqlalchemy/ext/declarative.py b/lib/sqlalchemy/ext/declarative.py index e22928b487..07974cacce 100644 --- a/lib/sqlalchemy/ext/declarative.py +++ b/lib/sqlalchemy/ext/declarative.py @@ -214,29 +214,39 @@ ORM function:: Table Configuration =================== -As an alternative to ``__tablename__``, a direct :class:`~sqlalchemy.schema.Table` construct may be -used. The :class:`~sqlalchemy.schema.Column` objects, which in this case require their names, will be -added to the mapping just like a regular mapping to a table:: +Table arguments other than the name, metadata, and mapped Column arguments +are specified using the ``__table_args__`` class attribute. This attribute +accommodates both positional as well as keyword arguments that are normally +sent to the :class:`~sqlalchemy.schema.Table` constructor. The attribute can be specified +in one of two forms. One is as a dictionary:: class MyClass(Base): - __table__ = Table('my_table', Base.metadata, - Column('id', Integer, primary_key=True), - Column('name', String(50)) - ) + __tablename__ = 'sometable' + __table_args__ = {'mysql_engine':'InnoDB'} -Other table-based attributes include ``__table_args__``, which is -either a dictionary as in:: +The other, a tuple of the form ``(arg1, arg2, ..., {kwarg1:value, ...})``, which +allows positional arguments to be specified as well (usually constraints):: class MyClass(Base): __tablename__ = 'sometable' - __table_args__ = {'mysql_engine':'InnoDB'} - -or a dictionary-containing tuple in the form -``(arg1, arg2, ..., {kwarg1:value, ...})``, as in:: + __table_args__ = ( + ForeignKeyConstraint(['id'], ['remote_table.id']), + UniqueConstraint('foo'), + {'autoload':True} + ) + +Note that the dictionary is required in the tuple form even if empty. + +As an alternative to ``__tablename__``, a direct :class:`~sqlalchemy.schema.Table` +construct may be used. The :class:`~sqlalchemy.schema.Column` objects, which +in this case require their names, will be +added to the mapping just like a regular mapping to a table:: class MyClass(Base): - __tablename__ = 'sometable' - __table_args__ = (ForeignKeyConstraint(['id'], ['remote_table.id']), {'autoload':True}) + __table__ = Table('my_table', Base.metadata, + Column('id', Integer, primary_key=True), + Column('name', String(50)) + ) Mapper Configuration ==================== @@ -468,6 +478,11 @@ def _as_declarative(cls, classname, dict_): elif isinstance(table_args, tuple): args = table_args[0:-1] table_kw = table_args[-1] + if len(table_args) < 2 or not isinstance(table_kw, dict): + raise exceptions.ArgumentError( + "Tuple form of __table_args__ is " + "(arg1, arg2, arg3, ..., {'kw1':val1, 'kw2':val2, ...})" + ) else: args, table_kw = (), {} diff --git a/test/ext/test_declarative.py b/test/ext/test_declarative.py index 1e2fc9b60d..224f41731a 100644 --- a/test/ext/test_declarative.py +++ b/test/ext/test_declarative.py @@ -450,6 +450,15 @@ class DeclarativeTest(DeclarativeTestBase): define) def test_table_args(self): + + def err(): + class Foo(Base): + __tablename__ = 'foo' + __table_args__ = (ForeignKeyConstraint(['id'], ['foo.id']),) + id = Column('id', Integer, primary_key=True) + + assert_raises_message(sa.exc.ArgumentError, "Tuple form of __table_args__ is ", err) + class Foo(Base): __tablename__ = 'foo' __table_args__ = {'mysql_engine':'InnoDB'}