Django 无法识别使用 RunSQL 迁移添加的列

问题描述 投票:0回答:1

我正在尝试将 SERIAL 非主列添加到现有表中。 Django 似乎不支持这一点(AutoField 必须是主要的,我无法将此字段设为主要)。

但是postgres确实支持SERIAL列,所以在生成的迁移文件中我可以添加以下操作:

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;"
        )
    ]

但是,Django 似乎并未“注册”此迁移的影响。也就是说,当再次运行

manage.py makemigrations
时,该工具将尝试在新的迁移中再次添加
referral_id

模型定义为

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}>"

我确实找到了一种方法来解决这个问题,在让迁移生成其代码之后,我可以随后插入一些覆盖的 SQL 语句。

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;"
        )
    ]

这确实有效,但似乎不是特别有效。有没有办法向 Django 标记我自己添加了此字段并且不需要添加列本身?

python django database postgresql migration
1个回答
0
投票

您可以利用 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,
        ),
    ],
)
© www.soinside.com 2019 - 2024. All rights reserved.