【问题标题】:Django postgres query results getting different results for different database fieldsDjango postgres查询结果为不同的数据库字段获得不同的结果
【发布时间】:2019-07-31 07:58:38
【问题描述】:

我在 PostgreSQL 中有 2 个简单的表。

表 1(将数字保存在 Varchar 中):

class Numbers_char_model(models.Model):

    number = models.CharField(max_length=256, blank=True, null=True)

表2(以整数保存数字):

class Numbers_int_model(models.Model):

    number = models.IntegerField(blank=True, null=True)

两个表中的数据相同。

id   number

1   ->  0

2   ->  20

3   ->  40

4   ->  70

5   ->  110

6   ->  150

当我点击以下查询时,它们都会给出不同的结果。

def number_query(request):

    ax_int = Numbers_int_model.objects.filter(number__lte='20')
    ax_char = Numbers_char_model.objects.filter(number__lte='20')

ax_int 输出 --> 0,20

ax_char 输出 --> 0,20,110,150

有人可以解决这个问题吗?

【问题讨论】:

    标签: python django postgresql django-views


    【解决方案1】:

    这是因为int比较和string比较不一样。字符串比较适用于每个字符到字符。对于您的情况,四个字符串的第一个字符是“0”、“2”、“1”、“1”。并且 2 大于所有这些。所以这种类型的输出。

    对于这种情况,首先我们需要将 number 字段转换为 int 然后我们这样做。 extralink 可以做到这一点

     Numbers_char_model.objects.extra({'number':  "CAST(number as INT)"}).filter_by(number__lte=20)
    

    参考:link

    【讨论】:

    • 那么有没有什么办法没有类型转换来执行上面的查询来得到像整数一的输出
    • 解决方案之一是手动循环并附加结果。我不知道更好的方法。需要上网查。
    • @c.grey 虽然循环是一种选择,但我认为这在数据库级别是可能的。我刚刚更新了我的答案。你能检查一下吗?
    【解决方案2】:

    Numbers_char_model 有一个CharField。你不能对字符串做小于或等于。 Numbers_int_model 有效,因为字符串 '20' 被 Django ORM 转换为 int。

    【讨论】:

      【解决方案3】:

      您可以在不使用extra(已弃用)的情况下将字符串转换为 int。以下应该会给您预期的结果(尽管使用 IntegerField 开始显然更聪明):

      from django.db.models import IntegerField
      from django.db.models.functions import Cast
      
      ax_char = (
          Numbers_char_model.objects
          .annotate(number_int=Cast('number', IntegerField()))
          .filter(number_int__lte=20)
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-06
        • 1970-01-01
        • 1970-01-01
        • 2020-10-13
        相关资源
        最近更新 更多