次のような Django (1.4.2) データ モデルがあります。
class CoreData(models.Model):
cdid = models.AutoField(primary_key=True,editable=False)
atr1 = # whatever
atr2 = # whatever
class EnvironData(models.Model):
cdid = models.ForeignKey(CoreData)
# etc
class TransactionData(models.Model):
edid = models.ForeignKey(EnvironData)
# etc
etc
トランザクション データを更新するアトミック トランザクションが必要です。
tdo = TransactionData.objects.select_for_update().get(etc=criteria)
# process transaction
# modify tdo object
tdo.save()
ここまでは順調ですね。ただし、 の過程でprocess transaction
、 と を確認する必要がCoreData.atr1
ありCoreData.atr2
ます。
それらにアクセスするtdo.edid.cdid.atr{1,2}
と、Django が不足しているデータを取得するため、追加の読み取り DB クエリが発生することを理解しています。(正直に言うと、それが 1 つだけであると 100% 確信しているわけではありません。また、2 つまたは 6 つになる可能性もありますが、私はそれを疑っています。)
一方、 I will と組み合わせるselect_related()
と、select_for_update()
ロックする必要のない (そしてすべきではない) データをロックするだけでなく、 のオーバーヘッドも作成されますtdo.save()
。
3 番目のアプローチは、( とは無関係のtdo
) 独立したクエリを介してデータをフェッチすることselect_related()
です。さらに、それは使用できますvalues()
。
この最後のアプローチが最も効率的だと思います。これは、既に as を持っているEnvironData
オブジェクトからクエリを開始できるためです。edid
tdo.edid_id
私の見解は正当ですか?もっと良い方法はありますか?
更新:個別にアクセスすることはまったく問題tdo.edid.cdid.atr{1,2}
ありません。トランザクション中に変更される可能性さえあります。これらは互いに独立しており、トランザクション全体で値を維持する必要がないためです。(ありがとう@Uszy Wieloryba)