1

我在 django 应用程序中有一个表,其中一个字段称为 Order(按排序顺序)并且是一个整数。每次输入新记录时,该字段都会自动递增到下一个数字。我的问题是,当一条记录被删除时,我希望其他记录向上移动一个数字,并且找不到任何可以重新计算表中所有记录并在删除记录时将它们向上移动一个数字的东西。

例如,表中有 5 条记录,其中订单号分别为 1、2、3、4 和 5。有人删除了 2 号记录,现在我希望将 3、4 和 5 号向上移动以获取已删除的 2 号记录放置所以订单号现在将是 1、2、3 和 4。python、postgres 和 django 有可能吗?

提前致谢!

4

7 回答 7

4

您将不得不自己实现该功能,我非常怀疑关系数据库是否会为您做到这一点,并且有充分的理由:这意味着在删除一行时更新潜在的大量行。

你确定你需要这个吗?它可能会变得昂贵。

于 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

而不是删除订单 - 您应该创建一个布尔字段(您可以随意调用它 - 例如,deleted)并将该字段设置1为“已删除”订单。

弄乱一个串行字段(这是您在 postgres 中调用的自动增量字段)将在以后导致问题;特别是如果您有外键和与表的关系。

它不仅会影响数据库服务器的性能;它也会影响您的业务,因为最终您将有两个具有相同订单号的订单浮动;即使您已经从数据库中“删除”了一个,订单号也可能已经在其他地方被引用——比如在您为客户打印的收据中。

于 2012-06-19T12:39:12.100 回答
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,一个缺失的 4,并且可能发生其他奇怪的事情。我继承了一个对应用程序至关重要的手动排序顺序的项目(还有其他问题),这一直是一个问题,只有 200-300 个项目。

处理手动排序顺序的正确方法是使用单独的表来管理它并使用连接进行排序。这样,您的 Order 表将正好有 10 个条目,其中只有 PK(订单号)和与要排序的项目 ID 的外键关系。已删除的项目将不再有参考。

您可以继续对删除进行排序,类似于您现在的操作方式,您只需将 Order 模型的 FK 更新为列表,而不是遍历和重写您的所有项目。效率更高。

这将轻松扩展到数百万个手动排序的项目。但是,您不想使用自动递增的整数,而是希望在您想要放置它的两个项目之间为每个项目提供一个随机订单 ID,并保持足够的空间(几十万应该这样做),这样您就可以任意重新-对它们进行排序。

我看到你提到你这里只有 10 行,但是第一次设计你的架构就可以很好地扩展,作为一种实践,这会让你在以后头疼,一旦你习惯了它,它就赢了真的不会再花时间了。

于 2013-02-25T19:18:57.643 回答
-1

尝试sequence使用 pgadmin 在 postgres 中设置类型的值。

于 2012-06-19T12:34:20.333 回答