]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
Support DROP CONSTRAINT IF EXISTS
authorAaron Griffin <aaron@growtherapy.com>
Thu, 24 Apr 2025 18:01:32 +0000 (13:01 -0500)
committerAaron Griffin <aaron@growtherapy.com>
Thu, 24 Apr 2025 18:01:32 +0000 (13:01 -0500)
alembic/ddl/impl.py
alembic/op.pyi
alembic/operations/base.py
alembic/operations/ops.py
alembic/operations/toimpl.py
tests/test_op.py

index 9331f363a15c924926a85b8607f51e27ede123e6..a10702231f1803129d4d11c558509d63b5ca99f9 100644 (file)
@@ -387,8 +387,8 @@ class DefaultImpl(metaclass=ImplMeta):
         if const._create_rule is None or const._create_rule(self):
             self._exec(schema.AddConstraint(const))
 
-    def drop_constraint(self, const: Constraint) -> None:
-        self._exec(schema.DropConstraint(const))
+    def drop_constraint(self, const: Constraint, **kw: Any) -> None:
+        self._exec(schema.DropConstraint(const, **kw))
 
     def rename_table(
         self,
index 14e6c39ae7fea1308bd14f2899b475b699451f93..ed7b9ded9e823e52045cff38c17f08222facf78b 100644 (file)
@@ -957,6 +957,7 @@ def drop_constraint(
     type_: Optional[str] = None,
     *,
     schema: Optional[str] = None,
+    if_exists: Optional[bool] = None,
 ) -> None:
     r"""Drop a constraint of the given name, typically via DROP CONSTRAINT.
 
@@ -968,6 +969,10 @@ def drop_constraint(
      quoting of the schema outside of the default behavior, use
      the SQLAlchemy construct
      :class:`~sqlalchemy.sql.elements.quoted_name`.
+    :param if_exists: If True, adds IF EXISTS operator when
+     dropping the constraint
+
+     .. versionadded:: 1.15.4
 
     """
 
index d7823a5bfe677924fbb74dbbc3b83608f04d46e3..afcb8ff971ee7097b1093853a6972937beea1d05 100644 (file)
@@ -1393,6 +1393,7 @@ class Operations(AbstractOperations):
             type_: Optional[str] = None,
             *,
             schema: Optional[str] = None,
+            if_exists: Optional[bool] = None,
         ) -> None:
             r"""Drop a constraint of the given name, typically via DROP CONSTRAINT.
 
@@ -1404,6 +1405,10 @@ class Operations(AbstractOperations):
              quoting of the schema outside of the default behavior, use
              the SQLAlchemy construct
              :class:`~sqlalchemy.sql.elements.quoted_name`.
+            :param if_exists: If True, adds IF EXISTS operator when
+             dropping the constraint
+
+             .. versionadded:: 1.15.4
 
             """  # noqa: E501
             ...
index 8c0bdf854af352aa0d5b2adfc8d200ad73eab74b..c80189955d70ca55c17b4fbf3a1f11845c6105a1 100644 (file)
@@ -140,12 +140,14 @@ class DropConstraintOp(MigrateOperation):
         type_: Optional[str] = None,
         *,
         schema: Optional[str] = None,
+        if_exists: Optional[bool] = None,
         _reverse: Optional[AddConstraintOp] = None,
     ) -> None:
         self.constraint_name = constraint_name
         self.table_name = table_name
         self.constraint_type = type_
         self.schema = schema
+        self.if_exists = if_exists
         self._reverse = _reverse
 
     def reverse(self) -> AddConstraintOp:
@@ -203,6 +205,7 @@ class DropConstraintOp(MigrateOperation):
         type_: Optional[str] = None,
         *,
         schema: Optional[str] = None,
+        if_exists: Optional[bool] = None,
     ) -> None:
         r"""Drop a constraint of the given name, typically via DROP CONSTRAINT.
 
@@ -214,10 +217,14 @@ class DropConstraintOp(MigrateOperation):
          quoting of the schema outside of the default behavior, use
          the SQLAlchemy construct
          :class:`~sqlalchemy.sql.elements.quoted_name`.
+        :param if_exists: If True, adds IF EXISTS operator when
+         dropping the constraint
+
+         .. versionadded:: 1.15.4
 
         """
 
-        op = cls(constraint_name, table_name, type_=type_, schema=schema)
+        op = cls(constraint_name, table_name, type_=type_, schema=schema, if_exists=if_exists)
         return operations.invoke(op)
 
     @classmethod
index 528c05428c910aba18639a9a60ac0f6dcd7377c2..c8190965adf09f3dd5dc58c291f4e8d7a4c58226 100644 (file)
@@ -197,13 +197,17 @@ def create_constraint(
 def drop_constraint(
     operations: "Operations", operation: "ops.DropConstraintOp"
 ) -> None:
+    kw = {}
+    if operation.if_exists is not None:
+        kw["if_exists"] = operation.if_exists
     operations.impl.drop_constraint(
         operations.schema_obj.generic_constraint(
             operation.constraint_name,
             operation.table_name,
             operation.constraint_type,
             schema=operation.schema,
-        )
+        ),
+        **kw
     )
 
 
index d9e65091fa5d62fd8131d88da73e8c2dbd10585c..4522e44c5da81d1afc2d0686a658c2ed7740840b 100644 (file)
@@ -821,6 +821,11 @@ class OpTest(TestBase):
         op.drop_constraint("foo_bar_bat", "t1", schema="foo")
         context.assert_("ALTER TABLE foo.t1 DROP CONSTRAINT foo_bar_bat")
 
+    def test_drop_constraint_if_exists(self):
+        context = op_fixture()
+        op.drop_constraint("foo_bar_bat", "t1", if_exists=True)
+        context.assert_("ALTER TABLE t1 DROP CONSTRAINT IF EXISTS foo_bar_bat")
+
     def test_create_index(self):
         context = op_fixture()
         op.create_index("ik_test", "t1", ["foo", "bar"])