如何阻止 Django/PSQL 在创建失败时自动递增 table ID
How to stop Django/PSQL from auto-incrementing table ID on creation failure
目前,我有一个带有 ItemReport
table 的 Django 项目,每个项目每天只允许 1 个条目。一切都很好,除了每当它因 IntegrityError 而失败时(即我的项目试图在 ItemReport
已经存在的那一天创建一个 ItemReport
,对象 ID 无论如何都会增加。
例如:
September 1:
Report for September 1 (ID 1)
September 2:
Report for September 1 (ID 1)
Report for September 2 (ID 5)
型号如下:
class ItemReport(BaseModel):
fk_item: Item = models.ForeignKey(Item, null=False)
date = models.DateField(default=now, null=False)
class Meta:
unique_together=(('fk_item', 'date'),)
class Item(BaseModel):
item_class = models.CharField(max_length=40, null=False)
name = models.CharField(max_length=80, unique=True, null=False)
每次用户登录时 运行 获取的代码:
for i in Item.objects.all():
try:
latest_ir = ItemReport.objects.create(fk_item=i)
print('Created Item Report!')
except IntegrityError as e:
print('ItemReport for {} for today already exists!'.format(i.name))
print('Created ItemReports!\n')
如果pk是自增字段则不能。当您尝试创建新对象时,数据库从序列中获取值。并且序列不支持回滚,因为当很多用户同时插入新行,只有一个被中止时,重建序列需要在数据库中进行多次硬操作。
希望对你有帮助。
在你问这个问题三年后,我遇到了同样的问题,但发现这个问题还没有在 SO 中得到解答,我想在这里留下我是如何解决这个问题的,以供未来的访问者使用。
之前,我使用下面的代码来防止重复错误。
try:
m = Modal(title='Title', content='Content.')
m.save()
except IntegrityError:
pass
但我遇到了和你一样的问题,每当它失败并显示 IntegrityError
对象 ID 无论如何都会递增。
我通过删除 try/except
块并使用 get_or_create()
而不是 save()
解决了这个问题。
Modal.objects.get_or_create(title='Title', content='Content.')
Django文档中get_or_create()
方法的详细解释:
https://docs.djangoproject.com/en/3.1/ref/models/querysets/#get-or-create
目前,我有一个带有 ItemReport
table 的 Django 项目,每个项目每天只允许 1 个条目。一切都很好,除了每当它因 IntegrityError 而失败时(即我的项目试图在 ItemReport
已经存在的那一天创建一个 ItemReport
,对象 ID 无论如何都会增加。
例如:
September 1:
Report for September 1 (ID 1)
September 2:
Report for September 1 (ID 1)
Report for September 2 (ID 5)
型号如下:
class ItemReport(BaseModel):
fk_item: Item = models.ForeignKey(Item, null=False)
date = models.DateField(default=now, null=False)
class Meta:
unique_together=(('fk_item', 'date'),)
class Item(BaseModel):
item_class = models.CharField(max_length=40, null=False)
name = models.CharField(max_length=80, unique=True, null=False)
每次用户登录时 运行 获取的代码:
for i in Item.objects.all():
try:
latest_ir = ItemReport.objects.create(fk_item=i)
print('Created Item Report!')
except IntegrityError as e:
print('ItemReport for {} for today already exists!'.format(i.name))
print('Created ItemReports!\n')
如果pk是自增字段则不能。当您尝试创建新对象时,数据库从序列中获取值。并且序列不支持回滚,因为当很多用户同时插入新行,只有一个被中止时,重建序列需要在数据库中进行多次硬操作。
希望对你有帮助。
在你问这个问题三年后,我遇到了同样的问题,但发现这个问题还没有在 SO 中得到解答,我想在这里留下我是如何解决这个问题的,以供未来的访问者使用。
之前,我使用下面的代码来防止重复错误。
try:
m = Modal(title='Title', content='Content.')
m.save()
except IntegrityError:
pass
但我遇到了和你一样的问题,每当它失败并显示 IntegrityError
对象 ID 无论如何都会递增。
我通过删除 try/except
块并使用 get_or_create()
而不是 save()
解决了这个问题。
Modal.objects.get_or_create(title='Title', content='Content.')
Django文档中get_or_create()
方法的详细解释:
https://docs.djangoproject.com/en/3.1/ref/models/querysets/#get-or-create