Opened 10 years ago
Last modified 10 years ago
#23609 closed Uncategorized
Migration fails on SQLite when removing a NULL constraint — at Initial Version
Reported by: | Markus Holtermann | Owned by: | Markus Holtermann |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.7 |
Severity: | Normal | Keywords: | |
Cc: | Markus Holtermann, Simon Charette | Triage Stage: | Unreviewed |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description
If a model has e.g IntegerField(null=True)
and a migration changes it to IntegerField(default=42)
the migration fails on SQLite due to the way the new table is created (create new table and copy old data into it). The respective SQL code Django produces is:
CREATE TABLE "testapp_foo__new" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "d" integer NOT NULL); INSERT INTO "testapp_foo__new" ("id", "d") SELECT "id", "d" FROM "testapp_foo";
The first idea for a patch was to do a two-step insert, first all rows w/o NULL values and second those w/ NULL and adding a the default explicitly. This would involve some more code changes. apollo13 came up with the idea to use a CASE WHEN
SQL syntax which, as it turns out, seems quite nice:
CREATE TABLE "testapp_foo__new" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "d" integer NOT NULL); INSERT INTO "testapp_foo__new" ("id", "d") SELECT "id", CASE WHEN "d" IS NULL THEN 42 ELSE "d" END FROM "testapp_foo";