18

Django (python) ですべてのオブジェクトの位置フィールドを特定の順序で一度に更新しようとしています。

これが私が今やっている方法ですが、問題はクエリが大量になることです。

    servers = frontend_models.Server.objects.all().order_by('-vote_count')

    i = 1
    for server in servers:
        server.last_rank = i
        server.save()
        i += 1

で更新する方法はありますか

Model.objects.all().order_by('some_field').update(position=some_number_that_changes_for each_object)

ありがとうございました!

4

2 に答える 2

14

F()from 式を使用django.db.modelsして同じことを行うことができます。

Model.objects.all().order_by('some_field').update(position=F(some_field)+1)

これにより、すべての列の値を更新する単一の SQL クエリが生成されるため、データベースにとっても効率的です。

于 2013-03-29T21:52:24.563 に答える
0

私の知る限り、Django のオブジェクト リレーショナル マッピング システムは、この更新操作を表現する方法を提供していません。ただし、SQL で表現する方法を知っている場合は、カスタム SQL クエリを介して実行できます。

from django.db import connection
cursor = connection.cursor()
cursor.execute('''UPDATE myapp_server ...''')

データベース エンジンが異なれば、この操作はさまざまな方法で表現されます。MySQL では、次のクエリを実行します。

SET @rownum=0;
UPDATE myapp_server A,
       (SELECT id, @rownum := @rownum + 1 AS rank
        FROM myapp_server
        ORDER BY vote_count DESCENDING) B
SET A.rank = B.rank
WHERE A.id = B.id

PostgreSQLでは、使用すると思います

UPDATE myapp_server A,
       (SELECT id, rownumber() AS rank
        OVER (ORDER BY vote_count DESCENDING)
        FROM myapp_server) B
SET A.rank = B.rank
WHERE A.id = B.id

(ただし、それはテストされていないため、注意してください!)。

于 2013-04-05T12:44:07.583 に答える