Django: 根据另一张表更新一张表

1 投票
1 回答
22 浏览
提问于 2025-04-13 13:32

我有两个表,分别叫做 Table1Table2,它们都有一个相同的字段,叫做 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(...)
# ...

有时候,我需要根据 Table1 中相同的 hash 值来更新 Table2 中的记录。但是我想用 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()
# ...

我该怎么做才能正确地实现这个呢?

1 个回答

1

你可以使用一个叫做 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 是什么。

撰写回答