Django: update one table based on another

23 Views Asked by At

I have two tables Table1 and Table2 with the same field 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(...)
# ...

Sometimes i need to update Table2 instances based on Table1 instances with the same hash. But i want to use Table2.objects.bulk_update(...) for it. Because there is too much instances to update them one by one like this:

# ...
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()
# ...

How can i do it properly?

1

There are 1 best solutions below

1
willeM_ Van Onsem On

You can work with a 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',
    ),
)

That being said, I don't think it is good to store the data in two tables, that is data duplication, which turns out to eventually cause more trouble. Usually it is better that there is one turth: one model that contains the data and thus determines what the name is in this case.