Вставка в Django JsonField без извлечения содержимого в память
У вас есть модель Django
class Employee(models.Model):
data = models.JSONField(default=dict, blank=True)
Это JSON-поле содержит данные за два года, как тонна данных.
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)
НО мне нужна сегодняшняя ДАТА, чтобы определить разные дни.
Итак, если мне не нужно вытаскивать колонку данных, мне не нужен kwargs dict. Допустим, я ничего не инициализирую (поэтому ничего не тяну в память), как я могу обновить колонку данных со словарем, который идентифицируется сегодняшней датой, так, чтобы после обновления колонка данных (JSONField) выглядела как {2021-08-10:{...}, 2021-08-11:{...}}
В реляционных базах данных можно хранить несколько элементов, принадлежащих одной и той же сущности, создав новую модель с привязкой 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']
В этом случае мы хотим добавить новый объект EmployeePresence
, который относится к объекту Employee
e
, поэтому мы создаем новый объект с:
EmployeePresence.objects.create(
date='2021-08-11',
data={'some': 'data', 'other': 'data'}
)
Мы можем получить доступ ко всем EmployeePresence
объектам данного Employee
объекта e
с помощью:
e.employeepresence_set.all()
создание, обновление, удаление одной записи EmployeePresence
, таким образом, упрощается и может быть эффективно выполнено с помощью запросов.