1

フィールドの1つがOrder(ソート順のように)と呼ばれ、整数であるdjangoアプリにテーブルがあります。新しいレコードが入力されるたびに、フィールドは次の番号に自動的にインクリメントされます。私の問題は、レコードが削除されたときに、他のレコードの数値を上にシフトさせ、レコードが削除された場合にテーブル内のすべてのレコードを再計算して数値を上にシフトするものを見つけることができないことです。

たとえば、テーブルには 5 つのレコードがあり、順序番号は 1、2、3、4、および 5 です。誰かがレコード番号 2 を削除したため、番号 3、4、および 5 を上に移動して、削除された番号 2 を取得したいと考えています。注文番号が1、2、3、および4になるように配置します.Python、postgres、およびdjangoで可能ですか?

前もって感謝します!

4

7 に答える 7

4

あなたはその機能を自分で実装する必要があります.リレーショナルデータベースがあなたのためにそれを行うとは思えません.正当な理由があります.1行が削除されたときに潜在的に多数の行を更新することを意味します.

本当にこれが必要ですか?それは高価になる可能性があります。

于 2012-06-19T12:36:02.097 に答える
2

ここで私が最終的に使用したもの:

item.delete()
items = table.objects.order_by('order')
count =0
for element in items:
  element.order = count
  element.save()
  count=count+1
于 2012-06-20T14:58:38.147 に答える
1

おそらく、テーブルの値をそのままにして、クエリを使用して番号付けを生成する方がよいでしょう。SQL を作成できる場合は、ウィンドウ関数を使用してこれを行うことができます。

SELECT
   output_column,
   ...,
   row_number() over (
     order by
       order_column)
FROM
  TheTable;
于 2012-06-19T18:19:52.583 に答える
0

シグナルpost_saveおよびpost_deleteを使用して、適切なオブジェクトを照会し、それらをソートしてから、欠落している番号を探し、必要に応じて再割り当て/保存してみてください。これは、多くのデータにとってはかなり重いかもしれませんが、めったに変更されない少数のアイテムについては、問題ありません。

from django.db.models.signals import post_delete
from django.dispatch import receiver

def fix_order(sorted_objects):
    #ensures that the given objects have sequential order values from 1 upwards
    i = 1
    for item in sorted_objects
        if item.order != i:
            item.order = i
            item.save()
        i += 1

@receiver(post_delete, sender=YourSortedModel)
def update_order_post_delete(sender, kwargs):
    #get the sorted items you need
    sort_items = YourSortedModel.objects.filter(....).order_by('order')
    fix_order(sort_items)
于 2012-06-19T13:40:45.320 に答える
0

私は何か他のものを探してこれに出くわし、何かを指摘したかった:

注文をデータと同じテーブルのフィールドに格納すると、データの整合性が失われます。または、インデックスを作成すると、競合が発生した場合に非常に複雑になります。言い換えれば、バグ (またはその他の何か) によって 3 が 2 つ出たり、4 が欠けたり、その他の奇妙なことが起こりやすいということです。私は、アプリケーションにとって重要な手動の並べ替え順序を使用してプロジェクトを継承しました (他にも問題がありました)。これは、200 ~ 300 個のアイテムで常に問題でした。

手動の並べ替え順序を処理する正しい方法は、別のテーブルを用意してそれを管理し、結合で並べ替えることです。このようにして、Order テーブルには、PK (注文番号) と、並べ替えたいアイテムの ID への外部キーの関係だけを持つ、ちょうど 10 個のエントリが含まれます。削除されたアイテムには、もはや参照がありません。

現在行っている方法と同様に削除の並べ替えを続行できます。すべてのアイテムを反復して書き直すのではなく、Order モデルの FK をリストに更新するだけです。はるかに効率的です。

これにより、手動でソートされた何百万ものアイテムに簡単にスケールアップできます。しかし、自動インクリメントされた int を使用するのではなく、配置したい 2 つのアイテムの間にランダムな順序 ID を各アイテムに与え、十分なスペースを確保する必要があります (数十万で十分です)。それらを並べ替えます。

ここには 10 行しかないとおっしゃいましたが、アーキテクチャを最初から適切にスケーリングできるように設計することは、練習として、今後の頭痛の種から解放されます。もう時間はかかりません。

于 2013-02-25T19:18:57.643 に答える
0

注文を削除する代わりに、ブール値のフィールドを作成し (任意の名前を付けます - たとえば、deleted)、このフィールドを1「削除された」注文用に設定します。

シリアル フィールド (postgres で自動インクリメント フィールドと呼ばれるもの) をいじると、後で問題が発生します。特に外部キーとテーブルとの関係がある場合。

データベース サーバーのパフォーマンスに影響を与えるだけではありません。また、最終的には同じ注文番号を持つ 2 つの注文が発生するため、ビジネスにも影響を与えます。データベースから「削除」したとしても、注文番号は別の場所で参照されている可能性があります。たとえば、顧客のために印刷した領収書などです。

于 2012-06-19T12:39:12.100 に答える
-1

sequencepgadminを使用してpostgresでtypeを使用して値を設定してみてください。

于 2012-06-19T12:34:20.333 に答える