【发布时间】:2023-03-03 00:45:01
【问题描述】:
我正在使用 Django Rest Framework 构建 REST API 应用程序。 通过发布请求,我正在接收数据并将其与citizen_id 和import_id unique_together 一起保存(参见models.py)。每次节省的 Import_id 都是通过 get_current_import_id() 函数计算的(参见 views.py) 对于并发请求,我使用“curl1 & curl2”命令 可能我不了解一些基础知识,但我想要的是保存每个并发请求(每个新请求都应该使用以前的 import_id + 1)。我还在序列化程序中使用“current_import_id”值来创建和保存实例。
P.S PATCH 和 GET 请求正在处理并发数据。例如两个并发的 PATCH 请求是随机保存的(有时“first”是第一个,有时“first”是第二个,但它有效)
POST 请求示例,JSON
{
"citizen_id": 1,
"name": "Foo",
}
models.py
class CitizenInfo(models.Model):
citizen_id = models.PositiveIntegerField()
import_id = models.PositiveIntegerField()
name = models.CharField(max_length=256)
class Meta:
unique_together = ('import_id', 'citizen_id',)
views.py 获取数据库中的最大 import_id 并确定 current_import_id
def get_current_import():
previous_import_id = CitizenInfo.objects.aggregate(
Max('import_id'))['import_id__max']
if not previous_import_id:
previous_import_id = 0
current_import_id = previous_import_id + 1
return current_import_id
目前我从 POST "curl1 & curl2" 命令获得的结果状态是 201 和 500(由于随机性,有时是 500 和 201)。
顺便说一句,我已经尝试过 django F() 和 select_for_update(nowait=True) 但它并没有像预期的那样有帮助
项目配置:Django + Gunicorn + Nginx
请多多指教。
【问题讨论】:
-
你是如何部署你的 Django 实例的?您使用的是什么 WSGI 服务器?开发服务器不是为并发而设计的,不得在生产中使用。
-
DJANGO + Gunicorn + nginx
-
您如何管理交易?你能分享你的
F()实现吗?这通常是处理此类并发问题的方式。我认为如果您正在使用select_for_update,您可能应该使用nowait=False,否则如果select_for_update无法获取锁,请求将失败。并确保您的数据库支持select_for_update。最后有什么理由不能将AutoField与pk=False一起使用? docs.djangoproject.com/en/2.2/ref/models/fields/#autofield -
使用
order_by()和first()而不是昂贵的聚合。还要确保您的列已编入索引。 -
@azundo,谢谢,我解决了这个问题,按照你说的改变我的 models.py。
标签: python django nginx django-rest-framework gunicorn