在GAE/gviz\u api上的JSON中浮动

2024-06-01 07:58:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个运行在googleappengines上的python应用程序,它以JSON格式输出数据,由gvizèu api构建,用于Google图表可视化。代码如下:

class StatsItem(ndb.Model):
    added      = ndb.DateTimeProperty(auto_now_add = True, verbose_name = "Upload date")
    originated = ndb.DateTimeProperty(verbose_name = "Origination date")
    host       = ndb.StringProperty(verbose_name = "Originating host")
    uptime     = ndb.IntegerProperty(indexed = False, verbose_name = "Uptime")
    load1      = ndb.FloatProperty(indexed = False, verbose_name = "1-min load")
    load5      = ndb.FloatProperty(indexed = False, verbose_name = "5-min load")
    load15     = ndb.FloatProperty(indexed = False, verbose_name = "15-min load")

class ChartDataPage(webapp2.RequestHandler):

    def get(self):
        span = int(self.request.get('span', 720))
        stats = StatsItem.query().order(-StatsItem.originated).fetch(span)

        header = { 'originated' : ("datetime", "date") }

        vars = []
        for v in self.request.get_all('v'):
            if v in StatsItem._properties.keys():
                vars.append(v)
                header[v] = ("number", StatsItem._properties[v]._verbose_name)

        data = []
        for s in stats:
            entry = { 'originated' : s.originated }
            for v in vars:
                entry[v] = getattr(s, v)
            data.append(entry)

        data_table = gviz_api.DataTable(header)
        data_table.LoadData(data)
        self.response.headers['Content-Type'] = 'application/json'
        self.response.out.write(data_table.ToJSonResponse(columns_order=(("originated",) + tuple(vars)),
                                                          order_by="originated"))

它可以正常工作,但是我得到了一个著名的关于float类型属性的问题,即我看到的输出(示例):

google.visualization.Query.setResponse({"status":"ok","table":{"rows":[{"c":[{"v":"Date(2013,11,19,12,55,22,460)"},{"v":0.33000000000000002}]},{"c":[{"v":"Date(2013,11,19,12,56,22,641)"},{"v":0.33000000000000002}]},{"c":[{"v":"Date(2013,11,19,12,57,22,747)"},{"v":0.28999999999999998}]},{"c":[{"v":"Date(2013,11,19,12,58,22,914)"},{"v":0.25}]},{"c":[{"v":"Date(2013,11,19,12,59,23,19)"},{"v":0.28000000000000003}]},{"c":[{"v":"Date(2013,11,19,13,0,23,169)"},{"v":0.28000000000000003}]},{"c":[{"v":"Date(2013,11,19,13,1,23,268)"},{"v":0.41999999999999998}]},{"c":[{"v":"Date(2013,11,19,13,2,23,385)"},{"v":0.40999999999999998}]},{"c":[{"v":"Date(2013,11,19,13,3,23,518)"},{"v":0.40999999999999998}]},{"c":[{"v":"Date(2013,11,19,13,4,23,643)"},{"v":0.40999999999999998}]}],"cols":[{"type":"datetime","id":"originated","label":"date"},{"type":"number","id":"load5","label":"5-min load"}]},"reqId":"0","version":"0.6"});

因此,值为0.33的浮点值(如数据存储查看器中所示)在JSON中表示为0.3300000000000002。虽然它的工作,这不仅是丑陋的,而且占用带宽,所以我想四舍五入到2位,即0.33。奇怪的是,在某些情况下,这种情况正在发生(见上面的0.25)。你知道吗

我正在从我的应用程序目录加载gviz\u api模块。你知道吗

我尝试过以下解决方案,但都不奏效:

  1. round()-在输入数据表之前对图形进行赋值(上述代码中的round(getattr(s,v))。它被调用了,因为我看到整数变成了浮点数,但是对上面的浮点数问题没有影响。

  2. Monkey-patching JSON既在GAE应用程序模块中,也在gviz\u api模块中。没有效果,代码只是没有被调用,好像它根本就不在那里。

  3. 重写gviz中的default()方法_api.DataTableJSONEncoder. 我想这是行不通的,因为它只会被未知的数据类型调用。

我还没有尝试处理用regexps生成的JSON字符串,如果可能的话,我希望避免这种情况。你知道怎么修吗?你知道吗


Tags: nameselfapijsonfalseverbosedatadate