2 回答
TA贡献1884条经验 获得超4个赞
引用Django 文档:
捕获数据库错误的正确方法是围绕一个原子块
这是您的代码的改编:
from django.db import IntegrityError, transaction
for json_obj in json_data:
order = Order(symbol=json_obj['order_id'], amount=json_obj['amnount'])
try:
with transaction.atomic():
order.save()
except IntegrityError as exception:
if 'UNIQUE constraint failed' in exception.args[0]:
print('duplicate order id => skip this')
continue
您还可以使用get_or_create来实现您想要的:
for json_obj in json_data:
obj, created = Order.objects.get_or_create(
symbol=json_obj['order_id'],
defaults={'amount': json_obj['amnount'])},
)
if not created:
print('order id already existing => skip this')
如果你想要一个快速的代码(根据你的评论),你可以使用bulk_create。
orders_to_create = []
for json_obj in json_data:
orders_to_create.append(Order(symbol=json_obj['order_id'], amount=json_obj['amnount']))
Order.objects.bulk_create(orders_to_create, ignore_conflicts=True)
请注意
在支持它的数据库上(除 Oracle 之外的所有数据库),将 ignore_conflicts 参数设置为 True 告诉数据库忽略无法插入任何未通过约束(例如重复唯一值)的行
在不使用ignore_conflicts设置的情况下,您可以执行以下操作:
orders_to_create = []
order_ids = [json_obj['order_id'] for json_obj in json_data]
existing_order_ids = Order.objects.filter(symbol__in=order_ids).values_list('symbol', flat=True)
for json_obj in json_data:
# this condition prevents any IntegrityError du to an existing order_id
if json_obj['order_id'] not in existing_order_ids:
orders_to_create.append(Order(symbol=json_obj['order_id'], amount=json_obj['amnount']))
Order.objects.bulk_create(orders_to_create)
TA贡献1829条经验 获得超4个赞
首先,transaction.atomic
装饰器将数据库提交推迟到装饰函数的末尾。因此,您的异常处理现在将不起作用,因为异常会在您的 try-except 块之外抛出。文档还建议您不要在原子块内捕获异常。
或许这也会给你带来一个麻烦TransactionManagementError
。如果在原子块内发生异常,则不允许执行任何数据库查询。
您应该将 try-except 移到您的函数之外并检查是否可以解决您的问题。
添加回答
举报