Django: обновление одной таблицы на основе другой
У меня есть две таблицы Table1
и Table2
с одним и тем же полем hash_str
.
from django.db import models
class Table1:
data = JSONField(...)
hash_str = CharField(...)
class Table2:
name = CharField(...)
parsed = DateTimeField(...)
hash_str = CharField(...)
is_updated = BooleanField(...)
# ...
Иногда мне нужно обновлять Table2
экземпляры на основе Table1
экземпляров с тем же хэшем. Но я хочу использовать Table2.objects.bulk_update(...)
для этого . Потому что экземпляров слишком много, чтобы обновлять их по одному вот так:
# ...
for t2_obj in Table2.objects.filter(is_updated=False):
t1_obj = Table1.objects.get(hash_str=t2_obj.hash_str)
t2_obj.name = t1_obj.data["name"]
t2_obj.parsed = t1_obj.data["parsed"]
t2_obj.is_updated = True
t2_obj.save()
# ...
Как мне правильно это сделать?
Вы можете работать с Subquery
[Django-doc]:
from django.db.models import OuterRef, Subquery
from django.db.models.functions import Coalesce
Table2.objects.filter(is_updated=False).update(
is_updated=True,
name=Coalesce(
Subquery(
Table1.objects.filter(hash_str=OuterRef('hash_str')).values(
'data__name'
)[:1]
),
'name',
),
parsed=Coalesce(
Subquery(
Table1.objects.filter(hash_str=OuterRef('hash_str')).values(
'data__parsed'
)[:1]
),
'parsed',
),
)
При этом я не думаю, что хорошо хранить данные в двух таблицах, это дублирование данных, которое в конечном итоге приводит к еще большим проблемам. Обычно лучше, чтобы была одна турель: одна модель, которая содержит данные и таким образом определяет, что name
является в данном случае.