【问题标题】:Django migration drops and re-adds same constraintDjango 迁移删除并重新添加相同的约束
【发布时间】:2017-12-22 07:12:00
【问题描述】:

问朋友...当我将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 是否只是为了删除约束并在我们更改字段时重新添加它?我想不出任何理由为什么会发生这种情况?存在外键约束时是否有无法执行的操作?

【问题讨论】:

  • 为什么关系的双方都有很多对很多的字段?这几乎肯定是错误的。
  • 我不...我正在向您展示新旧字段与新字段,其中新字段具有空白=True,而旧字段则没有。是同一个型号。我只是想表达我的改变很小,不应该与模型的数据库定义有任何关系。

标签: python django postgresql migration


【解决方案1】:

如果看起来您遇到了ticket 25253 中描述的错误。

【讨论】:

  • 似乎这个错误仍然存​​在于 Django 2.1.3 中。有解决办法吗?
  • 删除所有旧的迁移文件,删除并重新创建数据库并调用 makemigrations => migrate 为我解决了这个问题..
【解决方案2】:

如果您无法承受停机时间,请使用RunSQL 迁移操作和state_operations 作为解决方法。这将告诉 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 不会抱怨迁移状态与当前模型不匹配。 :)

【讨论】:

    猜你喜欢
    • 2018-08-05
    • 1970-01-01
    • 2011-08-06
    • 1970-01-01
    • 2013-10-10
    • 1970-01-01
    • 2019-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多