Django将大型数据集插入模型 - 如何延迟提交?

时间:2017-03-01 02:45:23

标签: django django-models

我正在开发一个项目,我需要将大文件插入到模型中(有时是几千兆字节)。因为文件可能很大,我采用的方法是按行读取,然后将其插入Django模型。

但是,当在进程中遇到错误时,如何取消整个操作?确保在处理整个文件后没有错误地提交行的正确方法是什么。

另一种方法是一次性创建所有模型对象并将其批量插入,这对大型数据集是否可行?它将如何运作。

这是我的代码:

class mymodel(models.Model):
    fkey1 = models.ForeignKey(othermodel1,on_delete=models.CASCADE)
    fkey2= models.ForeignKey(othermodel2,on_delete=models.CASCADE)
    field 1= models.CharField(max_length=25,blank=False)
    field 2= models.DateField(blank=False)
    ...
    Field 12= models.FloatField(blank=False)

从excel中将数据插入模型:

wb=load_workbook(datafile, read_only=True, data_only=True)
ws=wb.get_sheet_by_name(sheetName)
for row in ws.rows:
    if isthisheaderrow(row):
        #determine column arrangement and pass to next
        break
for row in ws.rows:
    if isthisheaderrow(row):
        pass
    elif isThisValidDataRow(row):
        relevantRow=<create a list of values>
        dictionary=dict(zip(columnNames,relevantRow))
        dictionary['fkey1']=othermodel1Object
        dictionary['fkey2']=othermodel2Object
        mymodel(**dictionary).save()

1 个答案:

答案 0 :(得分:0)

我应该看起来更难,提交可以被装饰器@transaction.atomic延迟。这里给出了更详细的描述:https://docs.djangoproject.com/en/1.11/topics/db/transactions/

代码是:

wb=load_workbook(trfile, read_only=True, data_only=True)
ws=wb.get_sheet_by_name(sheetName)
revenueSwitch=True
for row in ws.rows:
    if ifHeaderReturnIndex(row,desiredColumns):
        selectedIndex=ifHeaderReturnIndex(row, desiredColumns)
        outputColumnNames=[row[i].value.replace(" ", "") for i in selectedIndex]
        #output_ws.append(outputColumnNames)
        break
@transaction.atomic
def insertrows():
    for row in ws.rows:
        if ifHeaderReturnIndex(row,desiredColumns):
            pass
        elif isRowValid(row,selectedIndex):
            newrow=[row[i].value for i in selectedIndex]
            dictionary=dict(zip(outputColumnNames,newrow))
            dictionary['UniqueRunID']=run
            dictionary['SourceFileObject']=TrFile
            TransactionData(**dictionary).save()
insertrows()