Issue
I am trying to add a SERIAL non-primary column to an existing table. Django does not seem to have support for this (AutoField must be primary, and I cannot make this field primary).
However postgres does support SERIAL columns, so in the generated migration file I can add the following operation:
class Migration(migrations.Migration):
dependencies = [
...
]
operations = [
migrations.RunSQL(
sql="ALTER TABLE portal_referral ADD referral_id SERIAL;",
reverse_sql="ALTER TABLE portal_referral DROP referral_id;"
)
]
however, it does not appear that Django 'registers' the effects of this migration. That is to say, when running manage.py makemigrations
again, the tool will attempt to add referral_id
again in a new migration.
The model is defined as
class Referral(utils.UUIDPrimaryKeyBase, utils.TimeStampedModel):
data = models.JSONField(encoder=DjangoJSONEncoder)
supplier = models.ForeignKey(Supplier, blank=True, null=True, on_delete=models.PROTECT, related_name="referrals")
session_id = models.UUIDField(editable=False, blank=True, null=True, unique=True)
referral_id = models.IntegerField()
def __str__(self):
return f"<referral id={self.id} supplier={self.supplier}>"
I did find a way to work around this, where after letting the migration generate its code I can insert some overriding SQL statements afterwards.
class Migration(migrations.Migration):
dependencies = [
...
]
operations = [
migrations.AddField(
model_name='referral',
name='referral_id',
field=models.IntegerField(default=0),
preserve_default=False,
),
migrations.RunSQL(
sql="ALTER TABLE portal_referral DROP referral_id;",
reverse_sql="ALTER TABLE portal_referral ADD referral_id INT DEFAULT 0;"
),
migrations.RunSQL(
sql="ALTER TABLE portal_referral ADD referral_id SERIAL;",
reverse_sql="ALTER TABLE portal_referral DROP referral_id;"
)
]
This works, but doesn't seem particularly effective. Is there a way to flag to Django that I have added this field myself & it does not need to add the column itself?
Solution
You can utilize RunSQL state_operations
migrations.RunSQL(
sql="ALTER TABLE portal_referral ADD referral_id SERIAL;",
reverse_sql="ALTER TABLE portal_referral DROP referral_id;",
state_operations=[
migrations.AddField(
"referral",
"referral_id",
field=models.IntegerField(default=0),
preserve_default=False,
),
],
)
Answered By - iklinac
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.