• 
      

    Add the ability to evolve constraints on a model in Django 2.2+.

    Review Request #11121 — Created Aug. 4, 2020 and submitted — Latest diff uploaded

    Information

    Django Evolution
    master

    Reviewers

    Constraints are a feature available in Django 2.2+. They're a way of
    listing explicit constraints on a table, for ensuring that a set of
    fields are unique (potentially with a conditional query that must also
    be met), or for ensuring that a condition passes when inserting data.
    These are dependent on the support in the database backend.

    A previous change introduced signature storage for constraints, so we
    can track the history of constraints and make modifications. This change
    completes the support by allowing constraints to be modified through a
    ChangeMeta mutation, generating SQL to drop old constraints and add
    new ones.

    Not all constraint types are available for all databases, or all
    versions of databases. Right now, there are effectively three types of
    constraints (check constraints, unique constraints, and unique
    constraints with a condition). Django already calculates the support for
    each of these, and we make use of this when determining which
    constraints we can evolve. We also make use of their SQL for evolving
    the constraints.

    The exception, as always, is SQLite. We still need to perform table
    rebuilds to modify the constraints list. This is at least pretty easy.
    We simply add any new constraints when building the new table, and leave
    out any we want to drop.

    This change does introduce our first MySQL support that's dependent on a
    newer version of MySQL, or on MariaDB. MySQL does not support check
    constraints before MySQL 8.0.16 or MariaDB 10.2.1, and even with those
    versions Django won't generate SQL prior to Django 3.0. Since we're just
    checking calculated state to determine whether we can use these, there
    isn't really any impact to our evolution logic, though we do need to
    branch off the SQL tests a bit to expect the right SQL for the MySQL
    flavor/version.

    Unit tests pass for all versions of Django across all databases.

    Commits

    Files