【问题标题】:Django test error: Column does not existDjango测试错误:列不存在
【发布时间】:2018-05-18 18:27:28
【问题描述】:

PostgresqlDjango 2.0Python 3.6.4

在运行将字段名称 desktop_pay 更改为简单的 pay 的迁移后,运行 manage.py test 时出现错误,提示 pay 列不存在。

这里是迁移:

from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('instructions', '0055_auto_20180517_1508'),
    ]

    operations = [
        migrations.RenameField(
            model_name='instruction',
            old_name='desktop_pay',
            new_name='pay',
        ),
    ]

这是错误:

> python .\manage.py test
Creating test database for alias 'default'...
Traceback (most recent call last):
  File "C:\Python36\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
psycopg2.ProgrammingError: column instructions_instruction.pay does not exist
LINE 1: "...on"."quota", "instructions_instruction"."target", "instructi...
                                                              ^

如果我启动 psql 提示,我可以清楚地看到该列确实存在,至少在“真实”表中。

mydatabase=> \d+ instructions_instruction
                                                              Table "public.instructions_instruction"
       Column        |          Type          | Collation | Nullable |                       Default                        | Storage  | Stats target | Description
---------------------+------------------------+-----------+----------+------------------------------------------------------+----------+--------------+-------------
 id                  | integer                |           | not null | nextval('instructions_instruction_id_seq'::regclass) | plain    |              |
 quota               | smallint               |           | not null |                                                      | plain    |              |
 pay                 | numeric(5,2)           |           | not null |                                                      | main     |              |

### etc...

这里发生了什么?为什么 Django 找不到该列?我该如何调试?

【问题讨论】:

  • 您确定连接到正确的数据库吗? (我知道这是一个愚蠢的错误,但不知何故偶尔会发生)。
  • 嘿,公平的问题,但是是的。我正在连接到我在settings.py 中定义的数据库。
  • 是否有任何测试代码使用模型旧字段名称?或者任何派生类的模型?
  • 不,旧字段名称 desktop_pay 出现在我的代码中的唯一位置是在旧迁移中。
  • 您尝试通过 django admin 更改实例,如果它抛出相同的错误?

标签: python django postgresql


【解决方案1】:

我也遇到过这个问题。首先,我不明白为什么这个错误只在测试时出现。

然后我查看了回溯,发现 Django 无法运行与 Django 找不到的列无关的迁移之一。

手动编写迁移以使用自动生成的值填充对象 uuid 字段。我像往常一样导入模型Post

import uuid
from django.db import migrations

from posts.models import Post


def gen_uuid(apps, schema_editor):
    for post in Post.objects.all():
        post.uuid = uuid.uuid4()
        post.save(update_fields=["uuid"])


class Migration(migrations.Migration):

    dependencies = [
        ("posts", "0014_post_uuid"),
    ]

    operations = [
        migrations.RunPython(gen_uuid, reverse_code=migrations.RunPython.noop),
    ]

我不清楚为什么,但是这段代码在准备测试数据库时会中断迁移(并且在测试模式之外可以正常工作)。因此,任何以下迁移都不适用于测试数据库,这会导致 column does not exist 错误。

那该怎么办?使用 apps.get_model 而不是官方 Django 文档中关于编写迁移 https://docs.djangoproject.com/en/3.1/howto/writing-migrations/#migrations-that-add-unique-fields 中描述的那样。

类似的东西。

import uuid
from django.db import migrations
    
def gen_uuid(apps, schema_editor):
    Post = apps.get_model("posts", "Post")
    for post in Post.objects.all():
        post.uuid = uuid.uuid4()
        post.save(update_fields=["uuid"])

【讨论】:

  • 谢谢!我遇到了同样的情况,这节省了我的时间。
【解决方案2】:

当我的迁移以某种方式搞砸时,我遇到了这些“列不存在”错误,有时当我不小心删除/覆盖迁移时会发生这种情况,但我也只是通过运行典型的迁移而发生这种情况我真的无法解释。

所以我猜你必须查明迁移中的问题。对我有用的是,在确认我的架构实际上是我想要的之后,在场景 #2 here 的帮助下重置迁移。

【讨论】:

  • 做到了。所以这将(希望)在生产中工作,我必须检查我的 master 分支,使用您提供的链接重置迁移,将 master 合并到我的开发分支中,然后迁移新的更改。
  • 我的生产服务器也对这个解决方案很满意。
猜你喜欢
  • 2013-12-21
  • 1970-01-01
  • 1970-01-01
  • 2016-02-14
  • 2019-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多