【问题标题】:Keeping json data in the order it was inserted - django按插入顺序保持 json 数据 - django
【发布时间】:2013-10-03 19:49:06
【问题描述】:

我的 django 应用程序中有一个 JSONField。数据可能如下所示:

{
"05/2013" : 101,
"04/2013" : 100.9,
"03/2013" : 100.5,
"02/2013" : 100.3,
"01/2013" : 100.3
}

这是一个价格指数。当我从字段中获取数据时,我想保留插入数据的顺序。

我查看了使用OrderedDictadvanced option。 Dict(我猜)使用词法排序,因此输出会以这种格式丢失它的原始顺序。 我尝试将日期翻转为2012-012012-02 等格式,但输出仍然是乱码。部分输出:

"2011-08":104.2,
  "2011-09":104,
  "2011-02":102.3,
  "2011-03":102.5,
  "2011-01":102,
  "2011-06":104,
  "2011-07":103.7,
  "2011-04":103.1,
  "2011-05":103.6,
  "2013-04":100.9,
  "2013-05":101,
  "2012-10":106,
  "2012-11":105.5,

我不确定这是哪种类型,我在寻找解决方案方面落后了一步。 欣赏任何想法。

编辑: 这是模型字段声明

from jsonfield import JSONField
...
values = JSONField(null=True, blank=True, verbose_name=_("values"),load_kwargs={'object_pairs_hook': collections.OrderedDict})
...

【问题讨论】:

  • 如果您想保留插入顺序,您可能希望通过首先对旧值进行排序来填充您的字段。类似price = OrderedDict(sorted(price.items(), key=lambda t: t[0]))
  • @Germano - 你能解释一下你的答案吗 - 我不确定这条线的去向...... pre_save?
  • 我不知道您是否有旧数据库,或者您是从头开始,也不知道您是否打算一次插入多个项目。该信息将让您选择插入该代码的正确位置。
  • 字典根据定义是无序的。不是词汇或任何东西,即使顺序在单个会话中是一致的,也没有预期的顺序。话虽如此,我认为高级示例应该可以工作,但从您的回复来看,我认为它没有。您可以使用sorted(the_dict.items()) 轻松解决此问题,但这并不能解释为什么它不起作用。只要您的日期格式为yyyy-mm,词法排序就可以工作。
  • 我是从零开始的,所以我很灵活。大多数情况下,我会批量插入数据,但我可能会更新。在这个例子中 - 我很明显每个月都会添加一行。 @Wolph - 我是新手,但根据我在 github 上的文档中的理解,这应该保留它插入的顺序,而不是按项目排序(你怎么能这样做? .... json 可能会得到相当复杂)。

标签: django json


【解决方案1】:

如果您需要在 JSONFIeld 中维护键顺序,您可以覆盖原生 JSONField 的 db_type 以使用 json 而不是 jsonb:

class RawJSONField(JSONField):

    def db_type(self, connection):
        return 'json'

来自Postgres documentation

主要的实际区别在于效率。 json 数据类型存储输入文本的精确副本,处理函数必须在每次执行时重新解析;而 jsonb 数据以分解的二进制格式存储,由于增加了转换开销,因此输入速度稍慢,但处理速度明显加快,因为不需要重新解析。 jsonb 还支持索引,这是一个显着的优势。

如果您不需要根据 JSON blob 的内容对数据进行索引,并且确实需要维护在实例化字典时创建的键顺序(也许您正在使用假设的客户端库JSON 键顺序),那么这可能对你有用。

【讨论】:

  • 警告:将 Django3.0.6 升级到 Django3.1.2 时,此解决方法不起作用,其中 django.contrib.postgres.fields.JSONField 被 django.models.JSONField 替换。未来的读者可能会通过此错误报告查看这是否已解决:code.djangoproject.com/ticket/32135#ticket
  • 感谢@Michael 的提醒。从票证来看,这似乎不会得到支持,这非常令人失望。
  • @RedBlueThing 先生您好,您对 django 3.2.4 有任何修复吗,我现在正在处理这个 json 和 jsonb 问题,请看看我的问题:stackoverflow.com/questions/69317306/…
【解决方案2】:

这是一个有趣的问题,特别是因为无法保证 javascript 对象、JSON 本身或 python dict 中的字段顺序

考虑到上述情况,如果我们将在数据库 + 序列化 + 反序列化 + 表示的某种组合中正确设置订单,它将仅适用于这种(相当狭窄的)配置

例如django-jsonfield 将 JSON 序列化(默认情况下)到文本字段,因此在数据库级别它可能是安全的,但是从几个 json 模块(json、simplejson、ujson、yajl)反序列化到字典然后所有订单都丢失了/p>

django 1.9 引入了本机 postgresql JSONField - 在这里你甚至在数据库级别也没有保证,因为数据在内部存储为 jsonb - 二进制优化 JSON

在我看来,与其搜索序列化为OrderedDict,不如更改数据的存储方式,如果顺序很重要——让我们将数据存储在表中:

[{date: "05/2013", price: 101},
 {date: "04/2013", price: 100.9},
 {date: "03/2013", price: 100.5},
 {date: "02/2013", price: 100.3},
 {date: "01/2013", price: 100.3}]

我们有顺序保证,数据可以线性处理,不依赖特殊实现。

【讨论】:

    猜你喜欢
    • 2020-01-16
    • 2010-12-09
    • 1970-01-01
    • 1970-01-01
    • 2022-06-29
    • 1970-01-01
    • 2023-03-10
    • 2011-12-18
    • 2013-12-18
    相关资源
    最近更新 更多