【问题标题】:Insert into Django JsonField without pulling the content into memory插入 Django JsonField 而不将内容拉入内存
【发布时间】:2021-10-14 14:48:09
【问题描述】:

有一个 Django 模型

    class Employee(models.Model):
        data = models.JSONField(default=dict, blank=True)

这个 JSONField 包含两年的数据,就像大量的数据。

    class DataQUery:

        def __init__(self, **kwargs):
            super(DataQUery, self).__init__()
            self.data = kwargs['data'] #is pulling the data in memory, 
           #that's what I want to avoid

            # Then We have dictionary call today to hold daily data
            today = dict()
            # ... putting stuff in today

            # Then insert it into data with today's date as key for that day
            self.data[f"{datetime.now().date()}"] = today

            # Then update the database
            Employee.objects.filter(id=1).update(data=self.data)

我想插入数据列而不将其拉入内存。

是的,我可以将default=dict 更改为default=list 并直接这样做

            Employee.objects.filter(id=1).update(data=today)

但我需要今天的 DATE 来确定不同的日子。

所以如果我不需要拉数据列,我不需要kwargs dict。假设我没有初始化任何东西(所以没有将任何东西拉入内存),我如何使用由今天日期标识的字典更新数据列,这样在更新后,数据列 (JSONField) 将看起来像 {2021- 08-10:{...}, 2021-08-11:{..}}

【问题讨论】:

  • 我不清楚你的目标是什么。如果您使用.update(...),它将不会将数据加载到数据库中的内存中,而是进行简单的UPDATE ... 查询。
  • self.data = kwargs['data'] 正在拉取内存中的数据,这是我想要避免的
  • 但是kwargs['data'] 已经是一本字典了。该行唯一要做的就是将 reference 复制到已经存在的项目。
  • 所以如果我不需要拉数据列,我不需要kwargs dict。假设我没有初始化任何东西(所以没有将任何东西拉入内存),我如何使用由今天日期标识的字典来更新数据列,这样在更新日期字段之后将看起来像 {2021-08-10:{ ...},2021 年 8 月 11 日:{..}}
  • 对于关系数据库,使用带有ForeignKey 给员工的额外模型更有意义。虽然关系数据库确实有 JSON 字段,但这些字段仍然更侧重于表连接而不是 JSON。因此,JSON 通常只用于处理 非结构化 数据。

标签: python django postgresql django-models orm


【解决方案1】:

对于关系数据库,可以通过使用ForeignKey 为另一个模型创建一个新模型来存储属于同一实体的多个项目。因此,这意味着我们将其实现为:

class Employee(models.Model):
    # …
    pass

class EmployeePresence(models.Model):
    employee = models.ForeignKey(Employee, on_delete=models.CASCADE)
    date = models.DateField(auto_now_add=True)
    data = models.JSONField(default=dict, blank=True)

    class Meta:
        ordering = ['employee', 'date']

在这种情况下,我们希望添加一个与Employee 对象e 相关的新EmployeePresence 对象,因此我们创建一个新对象:

EmployeePresence.objects.create(
    date='2021-08-11',
    data={'some': 'data', 'other': 'data'}
)

我们可以通过以下方式访问给定Employee 对象e 的所有EmployeePresences:

e<strong>.employeepresence_set</strong>.all()

因此,创建、更新、删除单个 EmployeePresence 记录更加简单,并且可以通过查询有效地完成。

【讨论】:

    猜你喜欢
    • 2021-07-24
    • 2014-03-14
    • 1970-01-01
    • 2010-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-04
    • 2016-11-29
    相关资源
    最近更新 更多