【问题标题】:Django query to Postgres returning wrong column对 Postgres 的 Django 查询返回错误的列
【发布时间】:2020-03-03 18:01:52
【问题描述】:

我遇到了一个奇怪的问题,可能与我找不到的一些缓存有关。

我有以下型号:

class Incubadores(models.Model):
    incubador = models.CharField(max_length=10, primary_key=True)
    posicion = models.CharField(max_length=10)

class Tareas(TimeStampedModel):
    priority = models.CharField(max_length=20, choices=PRIORITIES, default='normal')
    incubador = models.ForeignKey(Incubadores, on_delete=models.CASCADE, null=True, db_column='incubador')
    info = JSONField(null=True)
    datos = JSONField(null=True)

    class Meta:
        ordering = ('priority','modified','created')

我之前没有参数 db_column,所以该字段的 Postgres 列是 incubador_id 我使用参数db_column 更改列的名称,然后我运行python manage.py makemgrations 和python manage.py migrate但我仍然将列作为incubadores_id每当我执行查询时,例如:

>>> tareas = Tareas.objects.all().values()
>>> print(tareas)
<QuerySet [{'info': None, 'modified': datetime.datetime(2019, 11, 1, 15, 24, 58, 743803, tzinfo=<UTC>), 'created': datetime.datetime(2019, 11, 1, 15, 24, 58, 743803, tzinfo=<UTC>), 'datos': None, 'priority': 'normal', 'incubador_id': 'I1.1', 'id': 24}, {'info': None, 'modified': datetime.datetime(2019, 11, 1, 15, 25, 25, 49950, tzinfo=<UTC>), 'created': datetime.datetime(2019, 11, 1, 15, 25, 25, 49950, tzinfo=<UTC>), 'datos': None, 'priority': 'normal', 'incubador_id': 'I1.1', 'id': 25}]>

我需要修改此列名称,因为我在使用序列化程序时遇到了其他问题。所以改变是必要的。

  • 如果我在其他模型中执行相同的查询,我也更改了默认字段的名称。问题完全一样。
  • 它发生在 shell 和代码上。
  • 我尝试了不同的查询,以确保它与 Django 惰性查询系统无关,但问题是相同的。我也试过执行django.db.connection.close()
  • 如果我直接对 PostgreSQL 进行 SQL 查询,它找不到incubador_id,而只能找到incubador,这是正确的。

有人知道会发生什么吗?我已经遇到这个问题两天了,我找不到原因:(这是一个非常基本的操作。

谢谢!

【问题讨论】:

  • 您的代码运行良好。 Django 为所有外键附加 _id 本身。如果您有名称为abc 的外键,则在您的数据库中它将保存为abc_idabc 将包含该外键的完整对象。
  • 你可以这样尝试Tareas.objects.all().values('id', 'incubador'),然后你就可以理解它运行良好了。
  • @MuhammadHassan,我的原始代码包含.values() 函数,但我简化了示例中的代码,因为它无论如何都会发生。参数db_column 删除了Django 添加的_id

标签: sql django postgresql django-models


【解决方案1】:

This answer 会解释为什么会这样。

Django 的内置序列化程序没有这个问题,但可能不会产生您想要的结果:

>>> from django.core import serializers
>>> serializers.serialize("json", Tareas.objects.all())
'[{"model": "inc.tareas", "pk": 1, "fields": {"priority": "normal", "incubador": "test-i"}}]'

可以在此处使用fields 属性,这似乎可以为您提供所需的内容。

您没有指定“序列化程序的其他问题”是什么,但我的建议是编写自定义序列化代码。依赖.values() 甚至serializers.serialize() 这样的东西对我来说有点太含蓄了;如果模型发生变化,编写显式序列化代码可以降低您意外破坏与序列化数据消费者的合同的可能性。

注意:请尝试制作您提供的示例minimal and reproducible。我删除了一些字段以使其与股票 Django 一起使用,这就是序列化值缺少字段的原因;在没有您使用的第三方应用程序的情况下,_id 问题仍然存在,并且已通过序列化程序解决。这也不是特定于 PG 的。它也发生在 sqlite 中。

【讨论】:

  • 谢谢!!这就是原因,我快疯了。
  • 关于序列化程序。我使用 DRF 的,我有一个错误,我试图以这种方式追踪。但我想我找到了原因。否则我也会在另一个线程中发布它。
  • 是的,看起来他们的序列化器应该是一个很好的、明确的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-10
  • 1970-01-01
  • 2015-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-03
相关资源
最近更新 更多