首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在产品Django部署中添加非空字段

问在产品Django部署中添加非空字段
EN

Stack Overflow用户
提问于 2018-07-20 18:26:09
回答 3查看 1.8K关注 0票数 3

我有一个带有PostgreSQL数据库的产品Django部署(Django 1.11)。我想在我的模型中添加一个非空字段:

代码语言:javascript
复制
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。

在这种情况下,如何将这个新的非空字段部署到我的应用程序中,而不让我的用户收到任何错误?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-08-01 14:02:31

迁移应该始终在部署开始时运行,否则会遇到其他问题。这个问题的解决方案是将更改分成两个部署。

在部署1中,字段需要为空( NullBooleanField或null=True)。您应该对处于这种状态的代码进行迁移,并确保如果字段的值为None,则其余代码不会崩溃。这是必要的,因为请求可以转到还没有新代码的服务器;如果这些服务器创建了模型的实例,那么它们将在字段为null的情况下创建它。

在部署2中,将字段设置为不可空,为此进行迁移,并删除为处理字段值为None的情况而编写的任何额外代码。如果该字段没有默认设置,则您为第二个部署进行的迁移将需要为该字段中具有None的对象填充值。

这两种部署技术也需要安全地删除字段,尽管看起来有点不同。为此,请使用库django-非推荐字段。在第一个部署中,您不推荐使用模型文件中的字段,并从代码中删除对该字段的所有引用。然后,在部署2中,实际从数据库中删除字段。

票数 2
EN

Stack Overflow用户

发布于 2019-02-27 17:17:22

您可以从NullBooleanField开始实现这一点:

  1. 将new_field = models.NullBooleanField(default=False)添加到模型中
  2. 使用makemigrations创建模式迁移1
  3. 改变模型使之具有new_field = models.BooleanField(default=False)
  4. 使用makemigrations创建模式迁移2
  5. 运行模式迁移1
  6. 更新生产代码
  7. 运行架构迁移2

如果旧的生产代码在步骤5和步骤6之间写入表,则将写入new_field的空值。在步骤6和步骤7之间会有一段时间,其中BooleanField可以有空值,当字段被读取时,它将为空。如果您的代码能够处理这个问题,那么您就可以了,然后第7步将所有这些空值转换为False。如果新代码无法处理这些空值,则可以执行以下步骤:

  1. 将new_field = models.NullBooleanField(default=False)添加到模型中
  2. 使用makemigrations创建模式迁移1
  3. 运行模式迁移1
  4. 更新生产代码
  5. 改变模型使之具有new_field = models.BooleanField(default=False)
  6. 使用makemigrations创建模式迁移2
  7. 运行模式迁移2
  8. 更新生产代码

*请注意,这些方法只在Postgres进行了测试。

票数 1
EN

Stack Overflow用户

发布于 2018-07-20 19:15:12

通常,django升级过程如下:

地方发展ENV:

  • 在本地更改模型
  • 迁移模型(python manage.py makemigrations)
  • 在本地测试您的更改
  • 提交&将更改推到(git)服务器

在生产服务器上:

  • 设定ENV参数
  • 从您的版本控制系统(git获取-全部;git重置-硬源/主)
  • 更新python依赖项(如pip安装-r requirements.txt)
  • 迁移(manage.py migrate_schemas)
  • 更新静态文件(python manage.py收藏品)
  • 重新启动django服务器(取决于服务器,但可能类似于‘’)
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51448420

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档