2

私のDjangoアプリにはユーザーモデルがあり、それらのユーザーには多くのトランザクションがあります。一部のビューでは、すべての取引金額の概要 (合計) が表示されます。これを「合計」と呼びましょう。これまでのところ、これは表示のために必要に応じて集計されています。

さて、この集計を基本的にユーザーが表示するすべてのページに追加したいと思います...したがって、新しいトランザクションごとに維持されるDB /モデルフィールドから取得することをお勧めします。私はそれを行う方法を知っています: User モデルに「合計」フィールドを追加し、必要に応じて更新します (Django ORM F() 式を使用して人種耐性を高めます)。ここまでは順調ですね。

私の質問は、初期の「合計」値の設定、これまでのすべてのトランザクションの追跡に関するものです (running-tally が実装される前)。

新しいトランザクションが到着しないメンテナンスウィンドウ中に、すべての User.total 値を現在の集計に初期化するデータ移行を実行できると思います。しかし、私はそれをしたくありません。私が最後に行った同様のビッグ データ移行では、予想よりも時間がかかりました。

新しいトランザクションも到着している間に、長い停止なしでキャッチアップの集計を行うための推奨される手法/トリックはありますか?

集計を維持する新しいコードがデプロイされた時点で、しきい値の日付 (または ID) より前のトランザクションのみを考慮するキャッチアップ データ移行を記述できると思います。(その後、システムが稼働している間にデータ移行を実行し、移行にどれだけ時間がかかっても、移行が完了したときにのみインターフェイスに新しい集計を表示します。)しかし、私はむしろこの日付/をコーディングしたくありませんid しきい値を移行ソース コードに追加します。この目的で使用できる南部のメタデータはありますか?

4

1 に答える 1

2

残念ながら、あなたが説明した問題に対する「万能」な解決策はありません。

何をすべきかをよく理解しているように見えるので、別の解決策を提案させてください。

多数のユーザーがいて、各ユーザーのトランザクションの量が少量または中程度であると仮定すると (1 人のユーザーのトランザクションの処理に時間がかからないようにするため)、南部のデータ移行で次のようなことを行うことができます (古いDjango 1.6 がリリースされる前に質問した Django トランザクション):

from django.db import transaction
for user in orm.User.objects.all():
    with transaction.commit_on_success():
        user._total = calculate_sum_of_transactions_for_user(user)
        user.transactions_migrated = True
        user.save()

次に、次のメソッドを User モデルに追加できます。

@property
def total(self):
    if self.transactions_migrated:
        return self._total
    else:
        return calculate_sum_of_transactions_for_user(user)

トランザクション作成コードは次のようになります。

class Transaction(models.Model):
    amount = models.DecimalField(...)

    def save(self, ...):
        super().save(...)
        if self.user.transactions_migrated:
            self.user._total = F('_total') + self.amount
            self.user.save()

フィールドを削除して、チェックtransactions_migratedに置き換えることもできます。_total is None

于 2014-05-18T12:24:41.920 に答える