【问题标题】:Django model inheritance error with PostgreSQLPostgreSQL 的 Django 模型继承错误
【发布时间】:2012-12-17 01:12:07
【问题描述】:

我正在从 MySQL 后端切换到 PostgreSQL 后端,并且遇到了一些模型继承问题。以下是模型示例:

class Parent(models.Model):
   key = models.Charfield(...)
   value = models.Charfield(...)
   content_type = models.ForeignKey(ContentType)
   object_id = models.CharField(max_length=200)
   content_object = generic.GenericForeignKey('content_type', 'object_id')

class Child1(Parent):
   pass 

class Child2(Parent):
   pass

我们有两个这样的子类的原因是,我们在另一个模型中模拟两个键/值对,并希望将它们分成两个表以便于查找。通用 FK 也用于将其附加到其他模型。这种继承设置在 MySQL 中运行良好,但是当我将其切换到 PostgreSQL 时,在尝试运行我们的测试时出现错误(但 syncdb 运行良好)。就好像 Django 可以接受这种关系,但 PostgreSQL 不喜欢正在生成的 SQL。当我查看从 syncdb 生成的内容时,我看到了:

CREATE TABLE "myapp_parent" (
"id" serial NOT NULL PRIMARY KEY,
"key" varchar(200) NOT NULL,
"value" varchar(200) NOT NULL,
"content_type_id" integer NOT NULL REFERENCES "django_content_type" ("id") DEFERRABLE  INITIALLY DEFERRED,
"object_id" varchar(200) NOT NULL);

CREATE TABLE "myapp_child1" (
"parent_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "myapp_parent" ("id") DEFERRABLE INITIALLY DEFERRED);

CREATE TABLE "myapp_child2" (
"parent_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "myapp_parent" ("id")    DEFERRABLE INITIALLY DEFERRED);

所以一切看起来都是正确的,然后当我运行我的测试时,我得到了这个:

Error: Database test_myapp couldn't be flushed. Possible reasons:
* The database isn't running or isn't configured correctly.
* At least one of the expected database tables doesn't exist.
* The SQL was invalid.
Hint: Look at the output of 'django-admin.py sqlflush'. That's the SQL this command    wasn't able to run.
The full error: column "id" of relation "myapp_child1" does not exist

当我运行刷新时:

SELECT setval(pg_get_serial_sequence('"myapp_child1"','id'), 1, false);

我尝试在子模型中手动添加一个 ID 字段作为主键,但 Django 抛出一个错误,指出它与父级的 ID 字段冲突。我该如何解决这个问题,以便 PostgreSQL 喜欢它?并提前感谢。

【问题讨论】:

  • 使用MySQL时,Django是否会在“myapp_child1”表中创建一个名为“id”的列?
  • 不,它没有。在两个数据库中,唯一的列是 parent_ptr_id
  • 听起来像一个 Django 错误。我简要浏览了他们的票务系统,但我没有看到。也许你应该报告它。 (但请稍等一下,看看 SO 上的其他人是否比我知道的更多。)
  • 阅读@danodonovan 文档链接,了解主键类型兼容性

标签: django postgresql inheritance model


【解决方案1】:

如果你在 django 中使用模型继承,你应该声明 class Parent 是抽象的

class Parent(models.Model):
    ...
    class Meta:
        abstract = True

请参阅docs。我想某些 postgres / mysql 差异仅针对符合标准的代码进行了测试-这可能就是您在这里遇到问题的原因。在进行这些更改后,我还推荐./manage.py syncdb ;-)

如果有疑问,并且在测试环境中,您可以删除表并重新开始

$ ./manage.py sqlclear | ./manage.py dbshell

【讨论】:

    【解决方案2】:

    您的模型必须包含一个 - 并且只有一个 - 目标模型的外键。如果您有多个外键,则会引发验证错误。这是django的限制之一。

    【讨论】:

    • "“object_id”字段不必与相关模型的主键字段类型相同,但它们的主键值必须强制与“object_id”类型相同字段由其 get_db_prep_value() 方法。"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-29
    • 1970-01-01
    • 2022-10-24
    相关资源
    最近更新 更多