#470: Add Field.db_default for defining database defaults
-------------------------------------+-------------------------------------
     Reporter:  jws                  |                    Owner:  John
                                     |  Whitlock
         Type:  New feature          |                   Status:  assigned
    Component:  Database layer       |                  Version:
  (models, ORM)                      |
     Severity:  normal               |               Resolution:
     Keywords:  sql schema           |             Triage Stage:  Accepted
    Has patch:  1                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  1
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by John Whitlock):

 I'm still in the code-reading and planning phase. This is a big one!

 A lot of the changes for PR 13709 were implemented in the database
 backend, such as quoting expressions and varying implementations. The
 reviewers prefer a `DefaultExpression` class, analogous to the
 `IndexExpression` class, and to use similar strategies as
 `IndexExpression` for backend-specific implementations. They also note
 that there is some support for database-level defaults in primary keys
 (PK), and wonder if a generic database-default field could borrow from the
 PK design, or if the PK feature could be built on top of a generic
 database-default field.

 Here's a rough idea of how this should work:

 * Tests may be needed to verify feature support in different backends,
 along with some new backend feature flags. For example:
     * [https://www.sqlite.org/lang_altertable.html sqlite3] supports
 `ALTER TABLE ADD COLUMN` for simple database defaults, but not for complex
 expressions. These can be supported by recreating the table, which is a
 more expensive option but commonly used for sqlite3 migrations.
     * [https://dev.mysql.com/doc/refman/8.0/en/data-type-defaults.html
 mysql 8.0.13] added support for default expressions
     * [https://www.postgresql.org/docs/9.5/dml-returning.html postgres]
 supports `RETURNING` to return database-created values, which may be
 useful
     * [https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf
 /ALTER-TABLE.html oracle] does not support bind variables in DDL
 statements, breaking a strategy in PR 13709.
 * Fields grow a new `db_default` parameter. It is distinct from the
 `default` parameter, and different combinations should be allowed. Simple
 values and more complicated expressions are allowed. Some expressions,
 such as a calculated value based on other fields, might be rejected at the
 Django level, and some may be rejected by the chosen backend. There are
 some checks that could be done at model initialization to verify a valid
 `db_default` value, with an appropriate new error message. There may be
 warnings for features supported on some but not all backends. The
 `default` value is preferred for saving, creating, and bulk-updating
 models - in other words, in every place where an application would pick an
 unspecified value - leaving current behavior unchanged.
 * If the `default` is not given but the `db_default` is, then a database
 read may be needed to determine the database-created value (such as with
 `refresh_from_db()`). If this is done anyway (for example, to determine
 the database-created primary key), it would be nice to get the
 `db_default`-initialized fields as well.
 * The migrations system should notice changes in the `db_default` field,
 and prepare a migration for it. There will be backend-specific strategies
 to implement migrations that change these fields.
 * Database introspecting should understand column defaults, and if
 possible add them when creating models from introspection.

 There may be more required features. I'm reading the Django database and
 test code to get familiar with them and to discover other features, and
 see if there is a way to break this into multiple PRs.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/470#comment:50>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/010701829ea017f7-031c38dd-e4ea-4a67-9e3e-98d25d1d7457-000000%40eu-central-1.amazonses.com.

Reply via email to