• 
      

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

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

    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.

    Summary ID
    Add the ability to evolve constraints on a model in Django 2.2+.
    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.
    0a630076655431a8668c59a26522891b4121281f
    Description From Last Updated

    F841 local variable 'table_name' is assigned to but never used

    reviewbotreviewbot

    F841 local variable 'deleted_constraints' is assigned to but never used

    reviewbotreviewbot
    Checks run (1 failed, 1 succeeded)
    flake8 failed.
    JSHint passed.

    flake8

    chipx86
    david
    1. Ship It!
    2. 
        
    chipx86
    Review request changed
    Status:
    Completed
    Change Summary:
    Pushed to master (75f72c5)