Django/Python中的自动增量字段

Django/Python中的自动增量字段,python,django,postgresql,Python,Django,Postgresql,我在django应用程序中有一个表,其中一个字段称为Order(如排序顺序),是一个整数。每次输入新记录时,字段自动递增到下一个数字。我的问题是当一条记录被删除时,我希望其他记录向上移动一个数字,但找不到任何可以重新计算表中所有记录并在记录被删除时将其向上移动一个数字的内容 例如,表中有5条记录,其中订单号为1、2、3、4和5。有人删除了记录编号2,现在我希望编号3、4和5向上移动,以取代删除的编号2,这样订单编号现在将是1、2、3和4。python、postgres和django有可能吗 提前

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

例如,表中有5条记录,其中订单号为1、2、3、4和5。有人删除了记录编号2,现在我希望编号3、4和5向上移动,以取代删除的编号2,这样订单编号现在将是1、2、3和4。python、postgres和django有可能吗


提前谢谢

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

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

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


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

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


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

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

弄乱一个串行字段(这就是你在postgres中所称的自动递增字段)会导致以后出现问题;特别是当您有外键和与表的关系时


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

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

处理串行字段(在postgres中称为自动递增字段)会导致以后出现问题;特别是当您有外键和与表的关系时

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

您可以尝试使用post_保存和post_删除来查询适当的对象,对它们进行排序,然后查找缺少的编号,并根据需要重新分配/保存。”。对于很多数据来说,这可能相当繁重,但对于很少更改的少数项目来说,这是可以的

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

您最好将表中的值单独保留,并使用查询生成编号。如果您正在编写一些SQL,那么可以使用窗口函数来实现这一点

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

您最好将表中的值单独保留,并使用查询生成编号。如果您正在编写一些SQL,那么可以使用窗口函数来实现这一点

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

以下是我最终使用的:

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

以下是我最终使用的:

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

我在寻找其他东西时遇到了这个问题,并想指出一些问题:

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

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

您可以像现在这样继续在delete上排序,只需更新订单模型的FK to list,而不是迭代并重新写入所有项目。效率更高

这将方便地扩展到数百万个手动排序的项目。但是,与使用自动递增的整数不同,您希望在要放置的两个项目之间为每个项目提供一个随机顺序id,并保留足够的空间(应该有几十万个),以便您可以任意重新排序它们


我看到你提到这里只有10行,但是第一次设计出可以很好扩展的架构,作为一种实践,会让你省去路上的麻烦,一旦你习惯了,就不会再花时间了。

我在寻找其他东西的时候遇到了这个问题,我想指出一点:

通过将顺序存储在与数据相同的表中的字段中,您将丢失数据完整性,或者如果对其进行索引,那么如果发生冲突,事情将变得非常复杂。换句话说