使用django orm更新表而不删除关系

时间:2018-01-19 19:54:39

标签: python mysql sql django orm

我有两个相关的django模型

class Item(models.Model):
    item_nbr = models.IntegerField(primary_key=True)
    created = models.DateTimeField(auto_now_add=True)
    item_nbr_desc = models.CharField(max_length=155)

class SetItem(models.Model):
    set_id = models.CharField(primary_key=True, default='', max_length=12)
    set_nbr = models.IntegerField()
    items = models.ForeignKey(Item)

我正在运行一个脚本(定期)从另一个数据库中读取Item ,并使用该数据帧更新django数据库项目表。我使用django orm框架与django数据库建立接口

script.py

from app.models import Item

item_table = pd.read_sql(__) 
item_table = some_transformations(item_table.copy())
#I remove all the Items that will be updated 
Item.objects.filter(item_nbr__in=item_table.item_nbr.unique()).delete()
item_table_records = item_table.to_dict('records')
item_instances = []
fields = item_table.keys()
for record in item_table_records:
    kwargs = {
             field: record[field] for field in fields
             }
    item_instances.append(Item(**kwargs))
Item.objects.bulk_create(item_instances) # update the new rows 

问题是每次删除相关项目时都会删除setItem表(因为on_delete=models.CASCADE行为)。我想更新items而不是删除setItem相关行,并且我不想更改on_delete默认行为,因为只有在此脚本中我才需要上传整个表,我可能想在另一个上下文中删除Item,我希望级联行为正常。我能做什么?它有一个批量更新功能,可以执行表的非破坏性更新?

2 个答案:

答案 0 :(得分:1)

您可以逐个更新项目:

items_by_pk = Item.objects.in_bulk(item_table.item_nbr.values)
for record in item_table.to_dict('records'):
    item = items_by_pk[record['item_nbr']]
    for field, value in record:
        setattr(item, field, value)
    item.save()

答案 1 :(得分:0)

添加@transaction.atomic decorator,并使用save()方法进行“批量”更新,而无需删除项目表。

from django.db import transaction

@transaction.atomic
def item_update(item_table):
    items_by_pk = Item.objects.in_bulk(item_table.item_nbr.values)
    for record in item_table.to_dict('records'):
        item = items_by_pk[record['item_nbr']]
        for field, value in record:
           setattr(item, field, value)
        item.save()

source