Opened 9 months ago

Closed 9 months ago

#35047 closed Bug (invalid)

Wrong sql query for migration

Reported by: mgoldenbe Owned by: nobody
Component: Migrations Version: 3.2
Severity: Normal Keywords: sqlmigrate
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by mgoldenbe)

I had the model:

class UserInfo(models.Model):
    user = models.ForeignKey(User, related_name='user_info', on_delete=CASCADE)
    picture = models.URLField(null = True, blank = True)
    paying = models.BooleanField(default = False)
    credits = models.DecimalField(max_digits=6, decimal_places=2)
    expiry = models.DateTimeField()
    usd_per_credit = models.FloatField(null = True, blank = True)
    content_count = models.IntegerField(default=0)
    suspended = models.BooleanField(default = False)
    suspended_request = models.TextField(null = True, blank = True)
    suspended_timestamp = models.DateTimeField(null = True, blank = True)

    def __str__(self): return str(self.user)

Then I changed the usd_per_credit field to be

    usd_per_credit = models.FloatField(default = 0.00)

After running makemigrations and migrate, I ran sqlmigrate and got the following:

BEGIN;
--
-- Alter field usd_per_credit on userinfo
--
ALTER TABLE "accounts_userinfo" ALTER COLUMN "usd_per_credit" SET DEFAULT 0.0;
UPDATE "accounts_userinfo" SET "usd_per_credit" = 0.0 WHERE "usd_per_credit" IS NULL;
ALTER TABLE "accounts_userinfo" ALTER COLUMN "usd_per_credit" SET NOT NULL;
ALTER TABLE "accounts_userinfo" ALTER COLUMN "usd_per_credit" DROP DEFAULT;
COMMIT;

The last line before COMMIT is wrong. It drops the default value which was correctly set.

Change History (3)

comment:1 by mgoldenbe, 9 months ago

Description: modified (diff)

comment:2 by mgoldenbe, 9 months ago

Code format

comment:3 by Tim Graham, 9 months ago

Resolution: invalid
Status: newclosed

Field.default doesn't set a permanent default at the database level. In this case, it is set temporarily to populate existing rows. To use a permanent database default, use Field.db_default (new in Django 5.0).

Note: See TracTickets for help on using tickets.
Back to Top