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 является в данном случае.

Вернуться на верх