Restore primary key field defaults and support for create()
#10958
#11792
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Types of changes
Description of Change
Restore model field-level defaults for primary keys.
Closes #10958
Before
Django 3.0 introduced an optimization for models with defaults defined on their primary key fields in a way that prevents "blind overwrites". By that, I mean creating an instance without fetching it from the database, assigning a primary key attribute manually, and saving it back, intending to potentially overwrite data. Arches does blind overwrites (e.g. in management commands with an
--overwrite
flag).The stopgap as part of Arches' upgrade to Django 3.2 was to remove field-level defaults altogether and add code to
__init__()
to set a value, but the problems with that are:create()
method without specifying the primary key, which is redundant and surprising. Support forcreate()
is blocking Interface for querying & updating resource models by node & nodegroup aliases #11595..pk = None
After
Field-level defaults are back, plus a solution to support blind overwrites (possible now on Django 5.1+, which supports
force_update=True
for a blind overwrite). Left a comment discouraging copying this pattern forward to future models.While here
db_default
(Django 5+) over our custom migration operations that were auto-creating UUID v1's.sqlmigrate
to crash, see Use db_default for auto-UUID fields in Django 5 #10958Issues Solved
Closes #10958
Checklist
Ticket Background
Further comments
The postgres rule checking for bidirectional concept relation uniqueness was preventing using db_default, giving this:
I worked around that by rewriting the rule as a functional
UniqueConstraint
, replacing the unique constraint we already had. Replacing 1 constraint and 1 rule with 1 constraint is presumably more efficient, but I haven't benched it. I added a test.