summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy')
-rwxr-xr-xlib/sqlalchemy/ext/declarative.py21
-rw-r--r--lib/sqlalchemy/schema.py79
2 files changed, 66 insertions, 34 deletions
diff --git a/lib/sqlalchemy/ext/declarative.py b/lib/sqlalchemy/ext/declarative.py
index 39aaf5488..898a9a728 100755
--- a/lib/sqlalchemy/ext/declarative.py
+++ b/lib/sqlalchemy/ext/declarative.py
@@ -819,7 +819,7 @@ from multiple collections::
__tablename__='my_model'
@declared_attr
- def __table_args__(self):
+ def __table_args__(cls):
args = dict()
args.update(MySQLSettings.__table_args__)
args.update(MyOtherMixin.__table_args__)
@@ -827,6 +827,25 @@ from multiple collections::
id = Column(Integer, primary_key=True)
+Creating Indexes with Mixins
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To define a named, potentially multicolumn :class:`.Index` that applies to all
+tables derived from a mixin, use the "inline" form of :class:`.Index` and establish
+it as part of ``__table_args__``::
+
+ class MyMixin(object):
+ a = Column(Integer)
+ b = Column(Integer)
+
+ @declared_attr
+ def __table_args__(cls):
+ return (Index('test_idx_%s' % cls.__tablename__, 'a', 'b'),)
+
+ class MyModel(Base,MyMixin):
+ __tablename__ = 'atable'
+ c = Column(Integer,primary_key=True)
+
Class Constructor
=================
diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py
index eb03fae98..df7dbace0 100644
--- a/lib/sqlalchemy/schema.py
+++ b/lib/sqlalchemy/schema.py
@@ -1543,7 +1543,23 @@ class Constraint(SchemaItem):
def copy(self, **kw):
raise NotImplementedError()
-class ColumnCollectionConstraint(Constraint):
+class ColumnCollectionMixin(object):
+ def __init__(self, *columns):
+ self.columns = expression.ColumnCollection()
+ self._pending_colargs = [_to_schema_column_or_string(c)
+ for c in columns]
+ if self._pending_colargs and \
+ isinstance(self._pending_colargs[0], Column) and \
+ self._pending_colargs[0].table is not None:
+ self._set_parent(self._pending_colargs[0].table)
+
+ def _set_parent(self, table):
+ for col in self._pending_colargs:
+ if isinstance(col, basestring):
+ col = table.c[col]
+ self.columns.add(col)
+
+class ColumnCollectionConstraint(ColumnCollectionMixin, Constraint):
"""A constraint that proxies a ColumnCollection."""
def __init__(self, *columns, **kw):
@@ -1563,21 +1579,12 @@ class ColumnCollectionConstraint(Constraint):
for this constraint.
"""
- super(ColumnCollectionConstraint, self).__init__(**kw)
- self.columns = expression.ColumnCollection()
- self._pending_colargs = [_to_schema_column_or_string(c)
- for c in columns]
- if self._pending_colargs and \
- isinstance(self._pending_colargs[0], Column) and \
- self._pending_colargs[0].table is not None:
- self._set_parent(self._pending_colargs[0].table)
+ ColumnCollectionMixin.__init__(self, *columns)
+ Constraint.__init__(self, **kw)
def _set_parent(self, table):
- super(ColumnCollectionConstraint, self)._set_parent(table)
- for col in self._pending_colargs:
- if isinstance(col, basestring):
- col = table.c[col]
- self.columns.add(col)
+ ColumnCollectionMixin._set_parent(self, table)
+ Constraint._set_parent(self, table)
def __contains__(self, x):
return x in self.columns
@@ -1798,7 +1805,7 @@ class UniqueConstraint(ColumnCollectionConstraint):
__visit_name__ = 'unique_constraint'
-class Index(SchemaItem):
+class Index(ColumnCollectionMixin, SchemaItem):
"""A table-level INDEX.
Defines a composite (one or more column) INDEX. For a no-frills, single
@@ -1808,7 +1815,7 @@ class Index(SchemaItem):
__visit_name__ = 'index'
- def __init__(self, name, *columns, **kwargs):
+ def __init__(self, name, *columns, **kw):
"""Construct an index object.
:param name:
@@ -1825,27 +1832,33 @@ class Index(SchemaItem):
Other keyword arguments may be interpreted by specific dialects.
"""
-
- self.name = name
- self.columns = expression.ColumnCollection()
self.table = None
- self.unique = kwargs.pop('unique', False)
- self.kwargs = kwargs
-
- for column in columns:
- column = _to_schema_column(column)
- if self.table is None:
- self._set_parent(column.table)
- elif column.table != self.table:
- # all columns muse be from same table
- raise exc.ArgumentError(
- "All index columns must be from same table. "
- "%s is from %s not %s" %
- (column, column.table, self.table))
- self.columns.add(column)
+ # will call _set_parent() if table-bound column
+ # objects are present
+ ColumnCollectionMixin.__init__(self, *columns)
+ self.name = name
+ self.unique = kw.pop('unique', False)
+ self.kwargs = kw
def _set_parent(self, table):
+ ColumnCollectionMixin._set_parent(self, table)
+
+ if self.table is not None and table is not self.table:
+ raise exc.ArgumentError(
+ "Index '%s' is against table '%s', and "
+ "cannot be associated with table '%s'." % (
+ self.name,
+ self.table.description,
+ table.description
+ )
+ )
self.table = table
+ for c in self.columns:
+ if c.table != self.table:
+ raise exc.ArgumentError(
+ "Column '%s' is not part of table '%s'." %
+ (c, self.table.description)
+ )
table.indexes.add(self)
@property