Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django应用程序中for循环中的原子事务_Python_Django_Postgresql_Django Orm - Fatal编程技术网

Python Django应用程序中for循环中的原子事务

Python Django应用程序中for循环中的原子事务,python,django,postgresql,django-orm,Python,Django,Postgresql,Django Orm,在我的django应用程序中,我有一个芹菜任务来处理用户上传的XLS文件。 它被用来做一些类似于“大规模导入”数据的事情 在for循环中,我正在处理每一行—我希望从每一行创建一个模型实例对象(因此我将有多个model.objects.create(…)调用—对于一行,我可能会创建多个对象及其外键) 在django中,是否可能对整个for循环有一个原子事务? 例如,如果XLS包含100行—其中90行成功,但91行没有成功(因为行中的数据错误)—是否可以回滚以前的90(或更多)DB保存 我的代码如下

在我的django应用程序中,我有一个芹菜任务来处理用户上传的XLS文件。 它被用来做一些类似于“大规模导入”数据的事情

在for循环中,我正在处理每一行—我希望从每一行创建一个模型实例对象(因此我将有多个model.objects.create(…)调用—对于一行,我可能会创建多个对象及其外键)

在django中,是否可能对整个for循环有一个原子事务? 例如,如果XLS包含100行—其中90行成功,但91行没有成功(因为行中的数据错误)—是否可以回滚以前的90(或更多)DB保存

我的代码如下所示:

workbook = xlrd.open_workbook(importobject.file.path)
worksheet = workbook.sheet_by_index(0)

processed_rows = []
omitted_rows = []

print('Mass import rows: ', worksheet.nrows)

startrange = 0

if str(worksheet.cell(0, 0).value) == 'header':
    print('Omit first row as header row')
    startrange = 1

for rowno in range(startrange, worksheet.nrows):
    logger.info('Processing row {}:'.format(rowno))

    for colno in range(worksheet.ncols):
        cell = worksheet.cell(rowno, colno)
        print('Row {}, Col {}:'.format(rowno, colno), str(cell.value))
        # process call and row
    # validate and save object here - if not valid - rollback whole mass import
    #MyModel.objects.create()

正如交易文档所指出的,您可以。在您的情况下,可以使用上下文管理器将其包装:

from django.db import transaction

with transaction.atomic():
    for rowno in range(startrange, worksheet.nrows):
        logger.info('Processing row {}:'.format(rowno))

        for colno in range(worksheet.ncols):
            cell = worksheet.cell(rowno, colno)
            print('Row {}, Col {}:'.format(rowno, colno), str(cell.value))
        if not ... valid:
            raise IntegrityError()  # will cause the entire transaction to be rolled back

如果不想引发异常,也可以使用
transaction.set\u rollback(True)