【问题标题】:How do I safely delete a model field in Django?如何安全地删除 Django 中的模型字段?
【发布时间】:2021-07-19 14:15:32
【问题描述】:

我需要从现有的 django 模型中删除已经有一些关联对象的字段。从models.py 中删除字段会给我一个错误(显然,因为仍有与它们关联的表列)。我的应用不需要body2body3 中的数据。 我已将该数据从这些字段复制到 body 字段。我将如何删除这些字段而不完全删除表?

class Post(models.Model):
    #some fields

    body =EditorJsField(editorjs_config=editorjs_config)
    body2 =EditorJsField(editorjs_config=editorjs_config)
    body3 =EditorJsField(editorjs_config=editorjs_config)

我删除了body2body3 并运行了迁移,在创建新对象时,我得到了这样的错误。

django.db.utils.IntegrityError: null value in column "body2" of relation "second_posts" violates not-null constraint
DETAIL:  Failing row contains (20, Wave | Deceptiveness, and unpredictability of nature, 2021-07-19 13:40:32.274815+00, 2021-07-19 13:40:32.274815+00, {"time":1626702023175,"blocks":[{"type":"paragraph","data":{"tex..., null, null, Just how unpredictable is nature? Nature is all around us, yet, ..., image/upload/v1626702035/dfaormaooiaa8felspqd.jpg, wave--deceptiveness-and-unpredictability-of-nature, #66c77c, l, 1, 1, 0).

这是我用来保存已清理数据的代码(当然是在我删除了这些字段之后。)

post = Posts.objects.create(
                body=form.cleaned_data.get('body'),
                #
            )

【问题讨论】:

标签: python django


【解决方案1】:

由于似乎没有人有答案,而且这个错误看起来是异常情况,所以我采用了非 Python 方式并运行 SQL 查询并删除了列。对于那些遇到同样问题的人,

警告,您将失去所有您要使用此方法删除的字段中的数据

首先,让 Django 了解这些变化

删除要删除的字段并运行迁移。

之前

class Post(models.Model):
    #some fields

    body =EditorJsField(editorjs_config=editorjs_config)
    body2 =EditorJsField(editorjs_config=editorjs_config)
    body3 =EditorJsField(editorjs_config=editorjs_config)

之后

class Post(models.Model):
    #some fields

    body =EditorJsField(editorjs_config=editorjs_config)

命令提示符

python manage.py makemigrations
python manage.py migrate

使用 SQL 查询删除列

首先连接到您的数据库(我使用了postgres)。表的名称应该类似于appname_model。我的应用程序被称为“Second”,模型是 Post。因此,该表被称为second_post

使用迁移后查看列是否仍然存在,

在 SQL 命令提示符中

/d second_post

这应该会给你一个很好的数据库图表,左侧列出了所有列。要删除这些列,请键入,

ALTER TABLE second_post DROP COLUMN body2;
ALTER TABLE second_post DROP COLUMN body3;

输入每个查询后,如果成功,提示应该返回一个字符串ALTER TABLE

【讨论】:

  • 您永远不应该手动执行此操作,因为它会使实际数据库状态与 Django 认为它应该看起来的样子不同步。请在更改之前和之后仔细检查您的迁移,因为在这种情况下它永远不需要任何手动数据库修改。如果您只有初始迁移和新迁移,请发布它们。如果您的问题中有更多问题,我可以帮助您提取相关问题,请进入chat 进行操作。
  • 如果您在执行上述操作时遇到错误,请确保从 models.py、admin.py 和 forms.py 中删除对该字段的任何引用。在我删除这些对该字段的引用后,上述解决方案效果很好。
【解决方案2】:

如果你想完全删除数据,你需要创建一个 Django 迁移(最好使用./manage.py makemigrations),它将从数据库中删除这些列。

或者,如果您想安全起见并保留旧数据,您可以先将这些字段设为可为空,然后为它们创建迁移,最后要么不再使用它们,要么从模型中删除这些列,但不要在迁移中反映它(尽管如果您需要在此应用中运行另一个迁移,您需要假装在迁移中删除了这些列)。

【讨论】:

  • 我实际上做了你的第一个建议,但那是我收到上述错误的时候。我认为这是我的数据库的问题。我可能需要运行 SQL 查询并删除这些列
  • 您运行迁移了吗?
  • 是的,我做到了。迁移运行良好。它正在创建一个我做不到的新对象
  • 这种特殊情况似乎是异常情况,因为makemigrations 没有删除这些列。迁移后我运行了 SQL 查询,结果很好。
  • @juztignoreme 手动从数据库中删除列可能会在未来引入更多问题。请参阅我对您的回答的评论。
猜你喜欢
  • 2016-04-18
  • 2012-07-17
  • 1970-01-01
  • 1970-01-01
  • 2011-06-13
  • 2012-01-05
  • 2021-05-07
  • 1970-01-01
  • 2018-05-03
相关资源
最近更新 更多