#23043 closed Bug (fixed)
Fix or document inconsistent handling of field defaults by migrations
Reported by: | Tim Graham | Owned by: | nobody |
---|---|---|---|
Component: | Migrations | Version: | 1.7-rc-1 |
Severity: | Release blocker | Keywords: | |
Cc: | Andrew Godwin, Shai Berger | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
If I create a model with the field my_field = models.CharField(max_length=200, default='Foo')
, there won't be a default set at the database level: question character varying(200) NOT NULL
. If I have that same field without a default
, but then add one in a migration, a default will be created in the database: question character varying(200) NOT NULL DEFAULT 'Foo'::character varying
. I think a default shouldn't be set in the latter case because we generally can't transform callable defaults into database defaults.
Change History (5)
comment:1 by , 10 years ago
Cc: | added |
---|---|
Severity: | Normal → Release blocker |
Triage Stage: | Unreviewed → Accepted |
Type: | Cleanup/optimization → Bug |
comment:2 by , 10 years ago
There is code in the schema backend specifically to remove defaults; since I'm on a plane for the next 12 hours I won't be able to investigate this further, but https://github.com/django/django/blob/master/django/db/backends/schema.py#L412 is supposed to drop the default on add and ensure this doesn't happen.
Can the reporter say what database backend they're using? Or someone else double-check this? The schema provided looks PostgreSQL-ish but I can't be certain.
I'm happy this being a blocker, we don't want to give the impression Django is setting database defaults now.
comment:3 by , 10 years ago
Yes, I tested with PostgreSQL, but it looks like it's probably an issue on all DBs. It looks like the BaseDatabaseSchemaEditor._alter_field()
method doesn't drop database defaults when it's finished.
comment:4 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
I think this is a bug, not a cleanup/optimization, and a release blocker at that.
South had added defaults in the database until version 0.7.4; I think it took another release or two to get rid of them completely. The realization that defaults should never be left in the database (they should only be used when adding new columns to existing tables, and then removed) was christened in pain and angst -- some related to callable, as @timo noted; another ill-effect, unique to Oracle, was that the presence of default date-time values required special, non-trivial handling for schema backup and restore (ask me if you want details; irrelevant here).
Defaults in a Django-managed database are evil. Kill them with fire.
(the change in type and severity is tentative, feel free to revert if you have can convince yourself otherwise)