0

時間の経過とともに変化する属性 (属性) を持つモデル (エンティティと呼びましょう) がありますが、その属性がデータベースでどのように変化するかの履歴を保持したいと考えています。マネージャーの属性の現在の値でエンティティをフィルター処理できる必要があります。しかし、Django (私が知る限り) ではネイティブに 1 つのクエリでこれを行うことはできないため、すべてのエンティティの Attribute の最新の値を生成するデータベース ビューを作成しました。したがって、私のモデル構造は次のようになります。

class Entity(models.Model):
    def set_attribute(self, value):
        self.attribute_history.create(value=value)

    def is_attribute_positive(self, value):
        return self.attribute.value > 0

class AttributeEntry(models.Model):
    entity = models.ForeignKey(Entity, related_name='attribute_history')
    value = models.IntegerField()
    time = models.DateTimeField(auto_now_add=True)

class AttributeView(models.Model)
    id = models.IntegerField(primary_key=True, db_column='id', 
        on_delete=models.DO_NOTHING)
    entity = models.OneToOneField(Entity, related_name='attribute')
    value = models.IntegerField()
    time = models.DateTimeField()

    class Meta:
        managed = False

私のデータベースには、次のような SQL で作成された現在の属性を生成するビューがあります。

CREATE VIEW myapp_attributeview AS
SELECT h1.*
FROM myapp_attributehistory h1
LEFT OUTER JOIN myapp_attributehistory h2
    ON h1.entity_id = h2.entity_id
        AND (h1.time < h2.time
        OR h1.time = h2.time
        AND h1.id < h2.id)
WHERE h2.id IS NULL;

私の問題は、set_attribute()チェックを使用してモデル オブジェクトに属性を設定するis_attribute_positive()と、Django が関連する AttributeView オブジェクトをキャッシュしている可能性があるため、常に機能するとは限らないことです。少なくともビューを再クエリすることで、Django にモデルを更新させるにはどうすればよいですか? attributeどういうわけかプロパティをダーティとしてマークできますか?

PS:私がこれを行っている理由は、のようなことができるようEntity.objects.filter(attribute__value__exact=...).filter(...)にするためです。そのため、誰かがその機能を取得する簡単な方法を知っていれば、そのような答えも受け入れられます!

4

2 に答える 2

0

問題を直接解決したことはありませんがis_attribute_positiive()、ビューの代わりにデータベース テーブルを直接クエリするように変更することで回避できました。

def is_attribute_positive(self, value):
    return self.attribute_history.latest().value > 0

そのため、このビューは Entity でクエリをフィルタリングできるという柔軟性を提供してくれますが、オブジェクトを受け取ったら、テーブルに基づくモデルを直接操作するのが最善の方法のようです。

于 2012-10-27T14:54:09.410 に答える
0

同じデータベースにアクセスする別のプロセス (おそらく Django でさえない) によって属性値が変更されていることを理解しています。そうでない場合は、django-reversionを確認してください。

一方、その場合は、この の 2 番目の回答を確認する必要があります。トランザクションをコミットするとクエリキャッシュが無効になり、このスニペットが提供されると書かれています。

>>> from django.db import transaction
>>> transaction.enter_transaction_management()
>>> transaction.commit() # Whenever you want to see new data
于 2012-10-25T18:42:54.867 に答える