From: Edgar Ramírez Mondragón Date: Thu, 18 Dec 2025 19:58:59 +0000 (-0500) Subject: Support for `IF EXISTS` in SQL Server 2016 (13.x) and later versions X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=40fc3c90e1fee3f7a19184ab57cca3cbcdfa6da1;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Support for `IF EXISTS` in SQL Server 2016 (13.x) and later versions Added support for the ``IF EXISTS`` clause when dropping indexes on SQL Server 2016 (13.x) and later versions. The :paramref:`.DropIndex.if_exists` parameter is now honored by the SQL Server dialect, allowing conditional index drops that will not raise an error if the index does not exist. Pull request courtesy Edgar Ramírez Mondragón. Fixes: #13045 Closes: #13046 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13046 Pull-request-sha: 65dca2055cb403430730b5cf42f0c5f55b23bfb1 Change-Id: Iab95b1a46003b38709a791b8a7c4233dfda5e830 --- diff --git a/doc/build/changelog/unreleased_20/13045.rst b/doc/build/changelog/unreleased_20/13045.rst new file mode 100644 index 0000000000..9ac8257451 --- /dev/null +++ b/doc/build/changelog/unreleased_20/13045.rst @@ -0,0 +1,9 @@ +.. change:: + :tags: usecase, mssql + :tickets: 13045 + + Added support for the ``IF EXISTS`` clause when dropping indexes on SQL + Server 2016 (13.x) and later versions. The :paramref:`.DropIndex.if_exists` + parameter is now honored by the SQL Server dialect, allowing conditional + index drops that will not raise an error if the index does not exist. + Pull request courtesy Edgar Ramírez Mondragón. diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py index 94f265ebed..32b845848d 100644 --- a/lib/sqlalchemy/dialects/mssql/base.py +++ b/lib/sqlalchemy/dialects/mssql/base.py @@ -963,6 +963,7 @@ import codecs import datetime import operator import re +from typing import Any from typing import Literal from typing import overload from typing import TYPE_CHECKING @@ -1014,6 +1015,7 @@ from ...types import VARCHAR from ...util import update_wrapper if TYPE_CHECKING: + from ...sql.ddl import DropIndex from ...sql.dml import DMLState from ...sql.selectable import TableClause @@ -2688,11 +2690,13 @@ class MSDDLCompiler(compiler.DDLCompiler): return text - def visit_drop_index(self, drop, **kw): - return "\nDROP INDEX %s ON %s" % ( - self._prepared_index_name(drop.element, include_schema=False), - self.preparer.format_table(drop.element.table), + def visit_drop_index(self, drop: DropIndex, **kw: Any) -> str: + index_name = self._prepared_index_name( + drop.element, include_schema=False ) + table_name = self.preparer.format_table(drop.element.table) + if_exists = " IF EXISTS" if drop.if_exists else "" + return f"\nDROP INDEX{if_exists} {index_name} ON {table_name}" def visit_create_table_as(self, element, **kw): prep = self.preparer diff --git a/test/dialect/mssql/test_compiler.py b/test/dialect/mssql/test_compiler.py index f8d9d54886..30e7f79a29 100644 --- a/test/dialect/mssql/test_compiler.py +++ b/test/dialect/mssql/test_compiler.py @@ -1534,6 +1534,14 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL): "DROP INDEX idx_foo ON bar.foo", ) + def test_drop_index_if_exists(self): + m = MetaData() + t1 = Table("foo", m, Column("x", Integer), schema="bar") + self.assert_compile( + schema.DropIndex(Index("idx_foo", t1.c.x), if_exists=True), + "DROP INDEX IF EXISTS idx_foo ON bar.foo", + ) + def test_index_extra_include_1(self): metadata = MetaData() tbl = Table(