diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-03-14 14:32:13 -0700 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-03-14 14:32:13 -0700 |
commit | 667f8f83fe2d41a7b53d854b3dbc45bd2cd9fbb0 (patch) | |
tree | 88e64857d240fce20cabd5aa7426c269a88af03c /lib/sqlalchemy | |
parent | 0b97ba8a1410447797c0a1d049b2cfb6cc066ff3 (diff) | |
download | sqlalchemy-667f8f83fe2d41a7b53d854b3dbc45bd2cd9fbb0.tar.gz |
- [feature] Added support for MySQL index and
primary key constraint types
(i.e. USING) via new mysql_using parameter
to Index and PrimaryKeyConstraint,
courtesy Diana Clarke. [ticket:2386]
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r-- | lib/sqlalchemy/dialects/mysql/base.py | 62 | ||||
-rw-r--r-- | lib/sqlalchemy/schema.py | 29 |
2 files changed, 69 insertions, 22 deletions
diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py index d71acbc59..d9ab5a34f 100644 --- a/lib/sqlalchemy/dialects/mysql/base.py +++ b/lib/sqlalchemy/dialects/mysql/base.py @@ -238,8 +238,29 @@ simply passed through to the underlying CREATE INDEX command, so it *must* be an integer. MySQL only allows a length for an index if it is for a CHAR, VARCHAR, TEXT, BINARY, VARBINARY and BLOB. +Index Types +~~~~~~~~~~~~~ + +Some MySQL storage engines permit you to specify an index type when creating +an index or primary key constraint. SQLAlchemy provides this feature via the +``mysql_using`` parameter on :class:`.Index`:: + + Index('my_index', my_table.c.data, mysql_using='hash') + +As well as the ``mysql_using`` parameter on :class:`.PrimaryKeyConstraint`:: + + PrimaryKeyConstraint("data", mysql_using='hash') + +The value passed to the keyword argument will be simply passed through to the +underlying CREATE INDEX or PRIMARY KEY clause, so it *must* be a valid index +type for your MySQL storage engine. + More information can be found at: + http://dev.mysql.com/doc/refman/5.0/en/create-index.html + +http://dev.mysql.com/doc/refman/5.0/en/create-table.html + """ import datetime, inspect, re, sys @@ -1439,35 +1460,50 @@ class MySQLDDLCompiler(compiler.DDLCompiler): table_opts.append(joiner.join((opt, arg))) return ' '.join(table_opts) + def visit_create_index(self, create): index = create.element preparer = self.preparer + table = preparer.format_table(index.table) + columns = [preparer.quote(c.name, c.quote) for c in index.columns] + name = preparer.quote( + self._index_identifier(index.name), + index.quote) + text = "CREATE " if index.unique: text += "UNIQUE " - text += "INDEX %s ON %s " \ - % (preparer.quote(self._index_identifier(index.name), - index.quote),preparer.format_table(index.table)) + text += "INDEX %s ON %s " % (name, table) + + columns = ', '.join(columns) if 'mysql_length' in index.kwargs: length = index.kwargs['mysql_length'] + text += "(%s(%d))" % (columns, length) else: - length = None - if length is not None: - text+= "(%s(%d))" \ - % (', '.join(preparer.quote(c.name, c.quote) - for c in index.columns), length) - else: - text+= "(%s)" \ - % (', '.join(preparer.quote(c.name, c.quote) - for c in index.columns)) + text += "(%s)" % (columns) + + if 'mysql_using' in index.kwargs: + using = index.kwargs['mysql_using'] + text += " USING %s" % (preparer.quote(using, index.quote)) + return text + def visit_primary_key_constraint(self, constraint): + text = super(MySQLDDLCompiler, self).\ + visit_primary_key_constraint(constraint) + if "mysql_using" in constraint.kwargs: + using = constraint.kwargs['mysql_using'] + text += " USING %s" % ( + self.preparer.quote(using, constraint.quote)) + return text def visit_drop_index(self, drop): index = drop.element return "\nDROP INDEX %s ON %s" % \ - (self.preparer.quote(self._index_identifier(index.name), index.quote), + (self.preparer.quote( + self._index_identifier(index.name), index.quote + ), self.preparer.format_table(index.table)) def visit_drop_constraint(self, drop): diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index 154e18e5f..d29514377 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -80,6 +80,17 @@ def _get_table_key(name, schema): else: return schema + "." + name +def _validate_dialect_kwargs(kwargs, name): + # validate remaining kwargs that they all specify DB prefixes + if len([k for k in kwargs + if not re.match( + r'^(?:%s)_' % + '|'.join(dialects.__all__), k + ) + ]): + raise TypeError( + "Invalid argument(s) for %s: %r" % (name, kwargs.keys())) + class Table(SchemaItem, expression.TableClause): """Represent a table in a database. @@ -435,14 +446,7 @@ class Table(SchemaItem, expression.TableClause): def _extra_kwargs(self, **kwargs): # validate remaining kwargs that they all specify DB prefixes - if len([k for k in kwargs - if not re.match( - r'^(?:%s)_' % - '|'.join(dialects.__all__), k - ) - ]): - raise TypeError( - "Invalid argument(s) for Table: %r" % kwargs.keys()) + _validate_dialect_kwargs(kwargs, "Table") self.kwargs.update(kwargs) def _init_collections(self): @@ -1814,7 +1818,8 @@ class Constraint(SchemaItem): __visit_name__ = 'constraint' def __init__(self, name=None, deferrable=None, initially=None, - _create_rule=None): + _create_rule=None, + **kw): """Create a SQL constraint. :param name: @@ -1844,6 +1849,10 @@ class Constraint(SchemaItem): _create_rule is used by some types to create constraints. Currently, its call signature is subject to change at any time. + + :param \**kwargs: + Dialect-specific keyword parameters, see the documentation + for various dialects and constraints regarding options here. """ @@ -1852,6 +1861,8 @@ class Constraint(SchemaItem): self.initially = initially self._create_rule = _create_rule util.set_creation_order(self) + _validate_dialect_kwargs(kw, self.__class__.__name__) + self.kwargs = kw @property def table(self): |