数据库错误,列不存在"但在manage.py sql中显示

3 投票
2 回答
6272 浏览
提问于 2025-04-17 12:42

关于Django和Python:

错误信息:

异常类型: DatabaseError
异常内容:
列 objects_thing.name_id 不存在
第 1 行: ...s_thing"."created", "objects_thing"."modified", "objects...

在我的 manage.py sql objects 中

CREATE TABLE "objects_thing" (
    otherstuff,
    otherstuff,
    "name_id" integer NOT NULL REFERENCES "profiles_name" ("id"),
    otherstuff,
);

所以这个列显然是存在的。
我已经运行了 syncdb。
为什么我会收到这个错误?我该如何解决这个问题?(我对这一切都很陌生)提前感谢你的帮助。

编辑:

Thing 模型:

class Thing(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    name = models.ForeignKey(Name)#The name for this thing
    current_allocation = models.DecimalField(max_digits=13, decimal_places=2, null=True, blank=True)
    target_allocation = models.DecimalField(max_digits=13, decimal_places=2, null=True, blank=True)
    placeholder = models.ForeignKey(Entity, null=True, blank=True, on_delete=models.SET_NULL)
    avatar = models.ImageField(upload_to='avatars/thing/', null=True, blank=True)

2 个回答

1

这个列可能并不存在。这个 SQL 命令只是显示了用来创建它的 SQL 语句,它是基于你当前的模型。你可以删除这个表,然后重新同步数据库,或者手动添加这个列。https://docs.djangoproject.com/en/dev/ref/django-admin/#sql-appname-appname

我觉得大家对 Django 模型和实际数据库表之间有点混淆。

Django 模型其实就是一些 Python 代码。它是一个与 SQL 表连接的 Python 对象。数据库的后端是在 settings.py 文件中指定的。数据库里才是真正的表。你遇到的错误表示 Python 模型和实际的数据库表不一致。

5

syncdb 这个命令不会改变你数据库中已经存在的表,所以如果你运行了这个命令,然后又修改了你的模型(model),那么你的模型就和它所代表的表不一致了。再次运行 syncdb 也无法解决这个问题。

你需要使用一些工具,比如 south 来进行迁移,或者直接从数据库中删除那个表,这样 syncdb 才能重新创建它,或者手动在数据库上运行一个 ALTER TABLE 命令。

编辑(更详细的说明)

当你在 models.py 中创建一个 Model 的子类时,它只是数据库表的一个 表示,并不会自动生成一个数据库表。你需要通过运行 python manage.py syncdb 来得到这个表。Django 会查看你所有的 models.py 文件,生成创建这个表所需的 SQL 语句,然后在你的数据库上执行。最终的结果就是你会得到与模型相关联的实际数据库表。

但是,syncdb 只会 创建 表,而不会修改它们。所以,如果你去修改了某个模型(比如添加字段、改变字段名称等),在数据库层面上并不会发生任何变化。再次运行 syncdb 也没有用,因为没有 新的 表需要创建。你必须以某种方式让表和模型相匹配,下面是你可以选择的几种方法:

  1. 使用 South(上面的链接)。South 让你可以创建 迁移,所以当你修改模型时,可以运行:

    python manage.py schemamigration --auto yourapp
    

    它会生成代码来修改表,使其与模型匹配。然后你只需应用这个迁移:

    python manage.py migrate yourapp
    

    这样就完成了。现在表和模型一致了,一切又回到了正轨。

  2. 你可以手动删除数据库中的表。你在生产环境中不想这样做,因为那样表中的所有数据都会被删除,但在开发环境中这样做应该没问题。删除表后,你可以运行:

    python manage.py syncdb
    

    因为表已经不存在了,Django 会根据你当前模型的状态重新创建它。最终结果是一样的,你的模型和表匹配了,所以可以继续工作了。

  3. 你可以手动修改表。这需要你弄清楚需要应用什么 SQL 来改变表,使其与模型匹配。你在数据库上运行这个 SQL,然后表就和模型一致了。

关键是,无论如何,你必须更新表,以反映你对模型所做的任何更改。模型并不是表,它只是表的一个程序化表示。

撰写回答