Skip to content

Commit

Permalink
Add documentation for SaferRemoveCheckConstraint
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelofern committed Jan 10, 2025
1 parent 3dd5dcc commit 2193ff0
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Tools to make Django migrations safer and more scalable.
- [Adding unique constraints](https://django-pg-migration-tools.readthedocs.io/en/latest/usage/operations.html#SaferAddUniqueConstraint)
- [Removing unique constraints](https://django-pg-migration-tools.readthedocs.io/en/latest/usage/operations.html#SaferRemoveUniqueConstraint)
- [Adding check constraints](https://django-pg-migration-tools.readthedocs.io/en/latest/usage/operations.html#SaferAddCheckConstraint)
- [Removing check constraints](https://django-pg-migration-tools.readthedocs.io/en/latest/usage/operations.html#SaferRemoveCheckConstraint)
- [Adding indexes (concurrently)](https://django-pg-migration-tools.readthedocs.io/en/latest/usage/operations.html#SaferAddIndexConcurrently)
- [Removing indexes (concurrently)](https://django-pg-migration-tools.readthedocs.io/en/latest/usage/operations.html#SaferRemoveIndexConcurrently)
- [Setting a column to NOT NULL](https://django-pg-migration-tools.readthedocs.io/en/latest/usage/operations.html#SaferAlterFieldSetNotNull)
Expand Down
74 changes: 74 additions & 0 deletions docs/usage/operations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,7 @@ Class Definitions
]
.. _safer_add_check_constraint:
.. py:class:: SaferAddCheckConstraint(model_name: str, constraint: models.CheckConstraint)
Provides a safer way to add a check constraint to an existing model.
Expand Down Expand Up @@ -725,6 +726,79 @@ Class Definitions
),
]
.. py:class:: SaferRemoveCheckConstraint(model_name: str, name: str)
Provides a way to drop a check constraint in a safer and idempotent
way.

:param model_name: Model name in lowercase without underscores.
:type model_name: str
:param name: The name of the constraint to be deleted.
:type name: str

**Why use this SaferRemoveCheckConstraint operation?**
------------------------------------------------------

The operation that Django provides (``RemoveConstraint``) has the
following limitations:

1. The operation fails if the constraint has already been removed.
2. When reverting, the alter table statement provided by Django to recreate
the constraint will block reads and writes on the table.

This custom operation fixes those problems by:

- Having a custom forward operation that will only attempt to drop the
constraint if the constraint exists.
- Having a custom backward operation that will add the constraint back
without blocking any reads/writes. This is achieved through the same
strategy of :ref:`SaferAddCheckConstraint <safer_add_check_constraint>`.

How to use
----------

1. Remove the check constraint in the relevant model as you would:

.. code-block:: diff
class Meta:
constraints = (
...
- models.CheckConstraint(
- check=~Q(id=42),
- name="id_cannot_be_42"
- ),
)
2. Make the new migration:

.. code-block:: bash
./manage.py makemigrations
3. The only changes you need to perform are: (i) swap Django's
``RemoveConstraint`` for this package's ``SaferRemoveCheckConstraint``
operation, and (ii) use a non-atomic migration.

.. code-block:: diff
+ from django_pg_migration_tools import operations
from django.db import migrations
class Migration(migrations.Migration):
+ atomic = False
dependencies = [("myapp", "0042_dependency")]
operations = [
- migrations.RemoveConstraint(
+ operations.SaferRemoveCheckConstraint(
model_name="mymodel",
name="id_cannot_be_42",
),
]
.. py:class:: SaferAddFieldOneToOne(model_name: str, name: str, field: models.OneToOneField)
Expand Down

0 comments on commit 2193ff0

Please sign in to comment.