Django迁移丢弃并重新添加相同的约束

时间:2017-07-17 16:40:28

标签: python django postgresql migration

向朋友询问...当我向模型字段添加blank=True时,有人可以解释为什么我的Django迁移正在下降并在我的表列上重新添加完全相同的约束吗?这是我对模特的改变:

# old definition
class CatalogCourse(models.Model):
    subjects = models.ManyToManyField(CatalogSubject, related_name="catalog_course_set")

# new definition with `blank=True`
class CatalogCourse(models.Model):
    subjects = models.ManyToManyField(CatalogSubject, related_name="catalog_course_set", blank=True)

当我makemigrations时,我得到了这次迁移:

class Migration(migrations.Migration):

    dependencies = [
        ('homepage', '0005_previous_migration'),
    ]

    operations = [
        migrations.AlterField(
            model_name='catalogcourse',
            name='subjects',
            field=models.ManyToManyField(blank=True, related_name='catalog_course_set', to='homepage.CatalogSubject'),
        ),
    ]

此迁移的SQL只是:

BEGIN;
--
-- Alter field subjects on catalogcourse
--
ALTER TABLE "homepage_catalogcourse_subjects" DROP CONSTRAINT "homepa_catalogsubject_id_304824f4_fk_homepage_catalogsubject_id";
ALTER TABLE "homepage_catalogcourse_subjects" ADD CONSTRAINT "homepa_catalogsubject_id_304824f4_fk_homepage_catalogsubject_id" FOREIGN KEY ("catalogsubject_id") REFERENCES "homepage_catalogsubject" ("id") DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE "homepage_catalogcourse_subjects" DROP CONSTRAINT "homepage_catalogcourse_id_cc699e39_fk_homepage_catalogcourse_id";
ALTER TABLE "homepage_catalogcourse_subjects" ADD CONSTRAINT "homepage_catalogcourse_id_cc699e39_fk_homepage_catalogcourse_id" FOREIGN KEY ("catalogcourse_id") REFERENCES "homepage_catalogcourse" ("id") DEFERRABLE INITIALLY DEFERRED;
COMMIT;

Django刚刚构建为删除约束并在我们改变字段的任何时候重新添加它吗?我想不出有什么理由需要发生?是否存在外键约束存在时无法执行的操作?

2 个答案:

答案 0 :(得分:4)

如果看起来像是在遇到ticket 25253中描述的错误。

答案 1 :(得分:0)

如果您无法承受停机时间,请使用state_operations的{​​{3}}迁移操作作为解决方法。这将告诉Django:就数据库状态而言,运行此SQL等效于这些操作。示例:

migrations.RunSQL(
   """--
   -- Alter field trip on payment
   --
   ALTER TABLE "myapp_payment" ALTER COLUMN "trip_id" DROP NOT NULL;
   """,
   state_operations=[
       migrations.AlterField(
           model_name='payment',
           name='trip',
           field=models.ForeignKey(blank=True, null=True,
                                   on_delete=django.db.models.deletion.PROTECT,
                                   related_name='payments', to='myapp.Trip'),
       ),
   ])

这样,我们仅应用所需的SQL,而Django不会抱怨迁移状态与当前模型不匹配。 :)