Django / Python中的自动增量字段

时间:2012-06-19 12:32:19

标签: python django postgresql

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

例如,表中有5条记录,其中订单号为1,2,3,4和5.有人删除了记录号2,现在我希望数字3,4和5向上移动以取得删除了2号位,所以订单号现在是1,2,3和4.是否有可能使用python,postgres和django?

提前致谢!

7 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:2)

这里我最终使用的是:

item.delete()
items = table.objects.order_by('order')
count =0
for element in items:
  element.order = count
  element.save()
  count=count+1

答案 2 :(得分:1)

最好不要仅仅在表中保留值并使用查询来生成编号。如果您要编写一些SQL,可以使用窗口函数来执行此操作。

SELECT
   output_column,
   ...,
   row_number() over (
     order by
       order_column)
FROM
  TheTable;

答案 3 :(得分:0)

您应该创建一个布尔字段(不管您喜欢什么,例如,deleted),而不是删除订单 - 并将此字段设置为1以获取“已删除”订单。< / p>

使用串行字段(这是在postgres中调用自动增量字段)会导致以后出现问题;特别是如果你有外键和与表的关系。

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

答案 4 :(得分:0)

您可以尝试使用signals 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)

答案 5 :(得分:0)

我遇到了这个寻找其他东西的东西,想要指出一些事情:

通过将订单存储在与数据相同的表中的字段中,您将失去数据完整性,或者如果您将其编入索引,如果遇到冲突,事情将变得非常复杂。换句话说,很容易有一个错误(或其他东西)给你两个3,一个失踪的4,以及其他奇怪的事情可能发生。我继承了一个项目,其中包含对应用程序至关重要的手动排序顺序(还有其他问题),这一直是一个问题,只有200-300项。

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

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

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

我看到你提到你在这里只有10行,但是设计你的架构以便第一次很好地扩展,作为一种练习,可以避免你的头痛,并且一旦你进入它的习惯,它不会再带你去了。

答案 6 :(得分:-1)

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