简体   繁体   中英

Atomic transactions in Django app in a for loop

In my django app I have a celery task which handles user-uploaded XLS file. Its being used to do something like "mass import" of data.

In for loop I am processing each row - from each row I want to create one model instance object (so I will have multiple Model.objects.create(...) calls - for one row its possible that I will create multiple objects and its foreign keys).

Is is possible in django to have an atomic transaction for whole for-loop? For example, if XLS contains 100 rows - and 90 of them are successful but 91 is not (because data in row is wrong) - is it possible to rollback previous 90 (or more) DB saves?

My code looks like:

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()

As the transactions docs note, you can control them explicitly . In your case you can wrap this with the context manager:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM