首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >django queryset从postgresql视图返回错误的值

django queryset从postgresql视图返回错误的值
EN

Stack Overflow用户
提问于 2012-08-02 16:28:57
回答 1查看 1.2K关注 0票数 3

我在这个装置的某个地方有个疯狂的窃听器。

数据库是Postgres9.1,是预先存在的(不是由Django管理的)。其中有一个表,然后有一些相当简单的视图,其中一个被定义为valid_logins_dow_popularity

代码语言:javascript
复制
 =>\d+ valid_logins_dow_popularity
             View "public.valid_logins_dow_popularity"
   Column   |       Type       | Modifiers | Storage | Description
------------+------------------+-----------+---------+-------------
 logins_avg | double precision |           | plain   |
 dow        | double precision |           | plain   |
View definition:
 WITH by_dow AS (
         SELECT valid_logins_over_time.count, date_part('dow'::text, valid_logins_over_time.date) AS dow
           FROM valid_logins_over_time
        )
 SELECT avg(by_dow.count)::double precision AS logins_avg, by_dow.dow
   FROM by_dow
  GROUP BY by_dow.dow
  ORDER BY by_dow.dow;

在Django 1.4中,我定义了一个使用该视图作为数据源的简单模型:

代码语言:javascript
复制
class ValidLoginsDowPopularity(models.Model):
    class Meta:
        db_table = 'valid_logins_dow_popularity'
        managed = False

    logins_avg = models.FloatField(
                            db_column='logins_avg')
    # Day of Week (dow)
    dow = models.IntegerField(db_column='dow',
                              primary_key=True)

    def __unicode__(self):
        return u"%d : " % (self.dow, self.logins_avg )

当我直接从DB获取数据时,我得到了一组数字:

代码语言:javascript
复制
SELECT "valid_logins_dow_popularity"."logins_avg", "valid_logins_dow_popularity"."dow" 
  FROM "valid_logins_dow_popularity";

    logins_avg    | dow
------------------+-----
 28.8571428571429 |   0
 95.1428571428571 |   1
 91.4285714285714 |   2
           89.625 |   3
 82.6666666666667 |   4
 61.4285714285714 |   5
 28.4285714285714 |   6
(7 rows)

当我通过Django模型获得数据时,我得到了一组关系模糊但不同的数字:

代码语言:javascript
复制
In [1]: from core.models import *

In [2]: v = ValidLoginsDowPopularity.objects.all()

In [3]: for i in v:
    print "logins_avg : %f | dow : %d" % (i.logins_avg, i.dow)
   ...:
logins_avg : 25.857143 | dow : 0
logins_avg : 85.571429 | dow : 1
logins_avg : 89.571429 | dow : 2
logins_avg : 86.375000 | dow : 3
logins_avg : 83.000000 | dow : 4
logins_avg : 67.000000 | dow : 5
logins_avg : 28.000000 | dow : 6

到目前为止,当直接从psql运行时,我已经验证了Django生成的sql返回预期的输出。我同样尝试过使用IntegerFieldFloatFieldDecimalField属性的Django模型--它们都有相同的值,但值不正确。我还编写了一个简单的测试程序,以绕过Django代码并确保它不是psycopg2问题:

代码语言:javascript
复制
import psycopg2

def main():
    conn_string = "dbname='********' user='*********'"

    conn = psycopg2.connect(conn_string)
    cursor = conn.cursor()

    sql = "select * from valid_logins_dow_popularity"
    cursor.execute(sql)

    for rec in cursor.fetchall():
        print rec

if __name__ == '__main__':
    main()

当运行时,给出正确的错误,因此psycopg2似乎在做正确的事情:

代码语言:javascript
复制
$ python test_psycopg2.py
(28.8571428571429, 0.0)
(95.1428571428571, 1.0)
(91.4285714285714, 2.0)
(89.625, 3.0)
(82.6666666666667, 4.0)
(61.4285714285714, 5.0)
(28.4285714285714, 6.0)

这怎麽可能?任何线索都会很感激的。我在哪里可以挖掘Django代码,看看哪里出了问题?我应该向Django项目报告这个问题吗?

EN

回答 1

Stack Overflow用户

发布于 2012-08-16 12:57:14

重新定义视图,并将值转换为数字而不是双值。在Django模型中,您需要一个与Postgres numeric匹配的numeric(如numeric(15,10) -> DecimalField(max_digits=15, decimal_places=10))。

在Django和db之间的浮点值方面,我从来没有任何运气,在其他软件与数据库对话时,我也遇到过类似的浮点问题。执行numeric <-> DecimalField是我找到的保证浮点值不会变得奇怪的唯一方法--通过将它们转换为定点值。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11781867

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档