summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2014-01-18 15:06:08 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2014-01-18 15:06:08 -0500
commit6e4fd0aea858338deca58f0e41bb01a584a79d39 (patch)
treea28e94a3d578ff49ea469abd33a2aab526d7445f
parent931655f41743a99521f60ebbd0b9199422099013 (diff)
parentcf8e5e3cf5b0e1be05a611c8828690acfcd2b9fa (diff)
downloadsqlalchemy-6e4fd0aea858338deca58f0e41bb01a584a79d39.tar.gz
Merge branch 'patch-msql-pkc-clustered' of bitbucket.org:dharland/sqlalchemy into m
-rw-r--r--lib/sqlalchemy/dialects/mssql/base.py79
-rw-r--r--lib/sqlalchemy/sql/compiler.py2
-rw-r--r--test/dialect/mssql/test_compiler.py23
-rw-r--r--test/sql/test_constraints.py22
4 files changed, 118 insertions, 8 deletions
diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py
index 90fd1f383..6c942b270 100644
--- a/lib/sqlalchemy/dialects/mssql/base.py
+++ b/lib/sqlalchemy/dialects/mssql/base.py
@@ -103,22 +103,49 @@ for these types will be issued as DATETIME.
.. _mssql_indexes:
-MSSQL-Specific Index Options
------------------------------
-
-The MSSQL dialect supports special options for :class:`.Index`.
+Clustered Index Support
+-----------------------
-CLUSTERED
-^^^^^^^^^^
+The MSSQL dialect supports clustered indexes (and primary keys) via the
+``mssql_clustered`` option. This option is available to :class:`.Index`,
+:class:`.UniqueConstraint`. and :class:`.PrimaryKeyConstraint`.
-The ``mssql_clustered`` option adds the CLUSTERED keyword to the index::
+To generate a clustered index::
Index("my_index", table.c.x, mssql_clustered=True)
-would render the index as ``CREATE CLUSTERED INDEX my_index ON table (x)``
+which renders the index as ``CREATE CLUSTERED INDEX my_index ON table (x)``.
.. versionadded:: 0.8
+To generate a clustered primary key use::
+
+ Table('my_table', metadata,
+ Column('x', ...),
+ Column('y', ...),
+ PrimaryKeyConstraint("x", "y", mssql_clustered=True))
+
+which will render the table, for example, as::
+
+ CREATE TABLE my_table (x INTEGER NOT NULL, y INTEGER NOT NULL, PRIMARY KEY CLUSTERED (x, y))
+
+Similarly, we can generate a clustered unique constraint using::
+
+ Table('my_table', metadata,
+ Column('x', ...),
+ Column('y', ...),
+ PrimaryKeyConstraint("x"),
+ UniqueConstraint("y", mssql_clustered=True),
+ )
+
+ .. versionadded:: 0.9
+
+MSSQL-Specific Index Options
+-----------------------------
+
+In addition to clustering, the MSSQL dialect supports other special options
+for :class:`.Index`.
+
INCLUDE
^^^^^^^
@@ -1023,6 +1050,42 @@ class MSDDLCompiler(compiler.DDLCompiler):
self.preparer.format_table(drop.element.table)
)
+ def visit_primary_key_constraint(self, constraint):
+ if len(constraint) == 0:
+ return ''
+ text = ""
+ if constraint.name is not None:
+ text += "CONSTRAINT %s " % \
+ self.preparer.format_constraint(constraint)
+ text += "PRIMARY KEY "
+
+ # support clustered option
+ if constraint.kwargs.get("mssql_clustered"):
+ text += "CLUSTERED "
+
+ text += "(%s)" % ', '.join(self.preparer.quote(c.name)
+ for c in constraint)
+ text += self.define_constraint_deferrability(constraint)
+ return text
+
+ def visit_unique_constraint(self, constraint):
+ if len(constraint) == 0:
+ return ''
+ text = ""
+ if constraint.name is not None:
+ text += "CONSTRAINT %s " % \
+ self.preparer.format_constraint(constraint)
+ text += "UNIQUE "
+
+ # support clustered option
+ if constraint.kwargs.get("mssql_clustered"):
+ text += "CLUSTERED "
+
+ text += "(%s)" % ', '.join(self.preparer.quote(c.name)
+ for c in constraint)
+ text += self.define_constraint_deferrability(constraint)
+ return text
+
class MSIdentifierPreparer(compiler.IdentifierPreparer):
reserved_words = RESERVED_WORDS
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py
index ade3c623a..5c5bfad55 100644
--- a/lib/sqlalchemy/sql/compiler.py
+++ b/lib/sqlalchemy/sql/compiler.py
@@ -2511,6 +2511,8 @@ class DDLCompiler(Compiled):
return preparer.format_table(table)
def visit_unique_constraint(self, constraint):
+ if len(constraint) == 0:
+ return ''
text = ""
if constraint.name is not None:
text += "CONSTRAINT %s " % \
diff --git a/test/dialect/mssql/test_compiler.py b/test/dialect/mssql/test_compiler.py
index 1742f024c..f12ab0330 100644
--- a/test/dialect/mssql/test_compiler.py
+++ b/test/dialect/mssql/test_compiler.py
@@ -510,6 +510,29 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
"CREATE TABLE test (id INTEGER NOT NULL IDENTITY(1,1))"
)
+ def test_table_pkc_clustering(self):
+ metadata = MetaData()
+ tbl = Table('test', metadata,
+ Column('x', Integer, autoincrement=False),
+ Column('y', Integer, autoincrement=False),
+ PrimaryKeyConstraint("x", "y", mssql_clustered=True))
+ self.assert_compile(schema.CreateTable(tbl),
+ "CREATE TABLE test (x INTEGER NOT NULL, y INTEGER NOT NULL, "
+ "PRIMARY KEY CLUSTERED (x, y))"
+ )
+
+ def test_table_uc_clustering(self):
+ metadata = MetaData()
+ tbl = Table('test', metadata,
+ Column('x', Integer, autoincrement=False),
+ Column('y', Integer, autoincrement=False),
+ PrimaryKeyConstraint("x"),
+ UniqueConstraint("y", mssql_clustered=True))
+ self.assert_compile(schema.CreateTable(tbl),
+ "CREATE TABLE test (x INTEGER NOT NULL, y INTEGER NULL, "
+ "PRIMARY KEY (x), UNIQUE CLUSTERED (y))"
+ )
+
def test_index_clustering(self):
metadata = MetaData()
tbl = Table('test', metadata,
diff --git a/test/sql/test_constraints.py b/test/sql/test_constraints.py
index 393bcd448..cb4b73ec8 100644
--- a/test/sql/test_constraints.py
+++ b/test/sql/test_constraints.py
@@ -544,6 +544,28 @@ class ConstraintCompilationTest(fixtures.TestBase, AssertsCompiledSQL):
"FOREIGN KEY(foo_bar) REFERENCES foo (bar))"
)
+ def test_empty_pkc(self):
+ # test that an empty primary key is ignored
+ metadata = MetaData()
+ tbl = Table('test', metadata,
+ Column('x', Integer, autoincrement=False),
+ Column('y', Integer, autoincrement=False),
+ PrimaryKeyConstraint())
+ self.assert_compile(schema.CreateTable(tbl),
+ "CREATE TABLE test (x INTEGER, y INTEGER)"
+ )
+
+ def test_empty_uc(self):
+ # test that an empty constraint is ignored
+ metadata = MetaData()
+ tbl = Table('test', metadata,
+ Column('x', Integer, autoincrement=False),
+ Column('y', Integer, autoincrement=False),
+ UniqueConstraint())
+ self.assert_compile(schema.CreateTable(tbl),
+ "CREATE TABLE test (x INTEGER, y INTEGER)"
+ )
+
def test_deferrable_column_check(self):
t = Table('tbl', MetaData(),
Column('a', Integer),