mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-05-12 03:38:35 -04:00
- Declarative supports a __table_args__ class variable, which
is either a dictionary, or tuple of the form
(arg1, arg2, ..., {kwarg1:value, ...}) which contains positional
+ kw arguments to be passed to the Table constructor.
[ticket:1096]
This commit is contained in:
@@ -83,6 +83,13 @@ CHANGES
|
||||
If you'd like them to return datetime objects anyway despite
|
||||
their accepting strings as input, make a TypeDecorator around
|
||||
String - SQLA doesn't encourage this pattern.
|
||||
|
||||
- extensions
|
||||
- Declarative supports a __table_args__ class variable, which
|
||||
is either a dictionary, or tuple of the form
|
||||
(arg1, arg2, ..., {kwarg1:value, ...}) which contains positional
|
||||
+ kw arguments to be passed to the Table constructor.
|
||||
[ticket:1096]
|
||||
|
||||
0.5beta1
|
||||
========
|
||||
|
||||
Vendored
+13
-3
@@ -171,11 +171,21 @@ As an alternative to `__tablename__`, a direct `Table` construct may be used. T
|
||||
Column('name', String(50))
|
||||
)
|
||||
|
||||
This is the preferred approach when using reflected tables, as below:
|
||||
Other table-based attributes include `__table_args__`, which is
|
||||
either a dictionary as in:
|
||||
|
||||
{python}
|
||||
class MyClass(Base):
|
||||
__table__ = Table('my_table', Base.metadata, autoload=True)
|
||||
class MyClass(Base)
|
||||
__tablename__ = 'sometable'
|
||||
__table_args__ = {'mysql_engine':'InnoDB'}
|
||||
|
||||
or a dictionary-containing tuple in the form
|
||||
`(arg1, arg2, ..., {kwarg1:value, ...})`, as in:
|
||||
|
||||
{python}
|
||||
class MyClass(Base)
|
||||
__tablename__ = 'sometable'
|
||||
__table_args__ = (ForeignKeyConstraint(['id'], ['remote_table.id']), {'autoload':True})
|
||||
|
||||
Mapper arguments are specified using the `__mapper_args__` class variable. Note that the column objects declared on the class are immediately
|
||||
usable, as in this joined-table inheritance example:
|
||||
|
||||
@@ -146,10 +146,19 @@ added to the mapping just like a regular mapping to a table::
|
||||
Column('name', String(50))
|
||||
)
|
||||
|
||||
This is the preferred approach when using reflected tables, as below::
|
||||
Other table-based attributes include ``__table_args__``, which is
|
||||
either a dictionary as in::
|
||||
|
||||
class MyClass(Base):
|
||||
__table__ = Table('my_table', Base.metadata, autoload=True)
|
||||
class MyClass(Base)
|
||||
__tablename__ = 'sometable'
|
||||
__table_args__ = {'mysql_engine':'InnoDB'}
|
||||
|
||||
or a dictionary-containing tuple in the form
|
||||
``(arg1, arg2, ..., {kwarg1:value, ...})``, as in::
|
||||
|
||||
class MyClass(Base)
|
||||
__tablename__ = 'sometable'
|
||||
__table_args__ = (ForeignKeyConstraint(['id'], ['remote_table.id']), {'autoload':True})
|
||||
|
||||
Mapper arguments are specified using the ``__mapper_args__`` class variable.
|
||||
Note that the column objects declared on the class are immediately usable, as
|
||||
@@ -237,11 +246,20 @@ def _as_declarative(cls, classname, dict_):
|
||||
if '__table__' not in cls.__dict__:
|
||||
if '__tablename__' in cls.__dict__:
|
||||
tablename = cls.__tablename__
|
||||
|
||||
table_args = cls.__dict__.get('__table_args__')
|
||||
if isinstance(table_args, dict):
|
||||
args, table_kw = (), table_args
|
||||
elif isinstance(table_args, tuple):
|
||||
args = table_args[0:-1]
|
||||
table_kw = table_args[-1]
|
||||
else:
|
||||
args, table_kw = (), {}
|
||||
|
||||
autoload = cls.__dict__.get('__autoload__')
|
||||
if autoload:
|
||||
table_kw = {'autoload': True}
|
||||
else:
|
||||
table_kw = {}
|
||||
table_kw['autoload'] = True
|
||||
|
||||
cols = []
|
||||
for key, c in our_stuff.iteritems():
|
||||
if isinstance(c, ColumnProperty):
|
||||
@@ -253,7 +271,7 @@ def _as_declarative(cls, classname, dict_):
|
||||
_undefer_column_name(key, c)
|
||||
cols.append(c)
|
||||
cls.__table__ = table = Table(tablename, cls.metadata,
|
||||
*cols, **table_kw)
|
||||
*(tuple(cols) + tuple(args)), **table_kw)
|
||||
else:
|
||||
table = cls.__table__
|
||||
|
||||
|
||||
+17
-1
@@ -2,7 +2,7 @@ import testenv; testenv.configure_for_tests()
|
||||
|
||||
from sqlalchemy.ext import declarative as decl
|
||||
from testlib import sa, testing
|
||||
from testlib.sa import MetaData, Table, Column, Integer, String, ForeignKey
|
||||
from testlib.sa import MetaData, Table, Column, Integer, String, ForeignKey, ForeignKeyConstraint
|
||||
from testlib.sa.orm import relation, create_session
|
||||
from testlib.testing import eq_
|
||||
from testlib.compat import set
|
||||
@@ -255,7 +255,23 @@ class DeclarativeTest(testing.TestBase, testing.AssertsExecutionResults):
|
||||
sa.exc.ArgumentError,
|
||||
"Mapper Mapper|User|users could not assemble any primary key",
|
||||
define)
|
||||
|
||||
def test_table_args(self):
|
||||
class Foo(Base):
|
||||
__tablename__ = 'foo'
|
||||
__table_args__ = {'mysql_engine':'InnoDB'}
|
||||
id = Column('id', Integer, primary_key=True)
|
||||
|
||||
assert Foo.__table__.kwargs['mysql_engine'] == 'InnoDB'
|
||||
|
||||
class Bar(Base):
|
||||
__tablename__ = 'bar'
|
||||
__table_args__ = (ForeignKeyConstraint(['id'], ['foo.id']), {'mysql_engine':'InnoDB'})
|
||||
id = Column('id', Integer, primary_key=True)
|
||||
|
||||
assert Bar.__table__.c.id.references(Foo.__table__.c.id)
|
||||
assert Bar.__table__.kwargs['mysql_engine'] == 'InnoDB'
|
||||
|
||||
def test_expression(self):
|
||||
class User(Base, ComparableEntity):
|
||||
__tablename__ = 'users'
|
||||
|
||||
Reference in New Issue
Block a user