我有一个带有PostgreSQL数据库的产品Django部署(Django 1.11)。我想在我的模型中添加一个非空字段:
class MyModel(models.Model):
new_field = models.BooleanField(default=False)为了进行部署,我需要首先更新服务器上的代码或运行迁移,但是因为这是一个生产部署,所以在更新数据库和更新服务器之间可以(而且会)发生请求。如果我首先更新服务器,我将得到一个OperationalError no such column,所以我显然需要首先更新数据库。
但是,当我首先更新数据库时,在使用新代码更新数据库之前,从服务器上发出的请求中得到以下错误:
django.db.utils.IntegrityError: NULL约束失败: myapp_mymodel.new_field
从表面上看,这是没有意义的,因为字段是默认的。进一步研究这一点,似乎只有Django逻辑提供了缺省值,而不是实际存储在SQL级别上。如果服务器没有更新的代码,它将不会将更新的列传递给SQL,而SQL将其解释为NULL。
在这种情况下,如何将这个新的非空字段部署到我的应用程序中,而不让我的用户收到任何错误?
发布于 2019-08-01 14:02:31
迁移应该始终在部署开始时运行,否则会遇到其他问题。这个问题的解决方案是将更改分成两个部署。
在部署1中,字段需要为空( NullBooleanField或null=True)。您应该对处于这种状态的代码进行迁移,并确保如果字段的值为None,则其余代码不会崩溃。这是必要的,因为请求可以转到还没有新代码的服务器;如果这些服务器创建了模型的实例,那么它们将在字段为null的情况下创建它。
在部署2中,将字段设置为不可空,为此进行迁移,并删除为处理字段值为None的情况而编写的任何额外代码。如果该字段没有默认设置,则您为第二个部署进行的迁移将需要为该字段中具有None的对象填充值。
这两种部署技术也需要安全地删除字段,尽管看起来有点不同。为此,请使用库django-非推荐字段。在第一个部署中,您不推荐使用模型文件中的字段,并从代码中删除对该字段的所有引用。然后,在部署2中,实际从数据库中删除字段。
发布于 2019-02-27 17:17:22
您可以从NullBooleanField开始实现这一点:
new_field = models.NullBooleanField(default=False)添加到模型中new_field = models.BooleanField(default=False)如果旧的生产代码在步骤5和步骤6之间写入表,则将写入new_field的空值。在步骤6和步骤7之间会有一段时间,其中BooleanField可以有空值,当字段被读取时,它将为空。如果您的代码能够处理这个问题,那么您就可以了,然后第7步将所有这些空值转换为False。如果新代码无法处理这些空值,则可以执行以下步骤:
new_field = models.NullBooleanField(default=False)添加到模型中new_field = models.BooleanField(default=False)*请注意,这些方法只在Postgres进行了测试。
发布于 2018-07-20 19:15:12
通常,django升级过程如下:
地方发展ENV:
在生产服务器上:
https://stackoverflow.com/questions/51448420
复制相似问题