1

I'm trying to test a view that imports csv file and creates Product objects. The problem is that it returns this error:

line 447, in validate_no_broken_transaction
    raise TransactionManagementError(
django.db.transaction.TransactionManagementError: An error occurred in the current transaction. You can't execute queries until the end of the 'atomic' block.

The error is caused by this row:

 Supplier.objects.get_or_create(name__iexact=supplier__name, defaults={'name': supplier__name})[

This is the method:

@classmethod
def import_csv(cls, filepath: str, created_by: User, delete_file=True) -> int:
    """imports products
    SKU already exists ? skip product : add product """
    from products.models import Product
    from products.models import Supplier
    products_count = 0
    EXCLUDED_ATTRS = ['id', 'supplier']

    with open(filepath) as f:
        reader = csv.DictReader(f)

        for row in reader:
            if not all([row.get(field, None) is not None for field in ['sku', 'supplier__name']]):
                continue

            product = Product()
            product.created_by = created_by

            for attr, val in row.items():
                if hasattr(product, attr) and attr not in EXCLUDED_ATTRS:
                    if attr == 'title':
                        setattr(product, attr, val[:99])
                    else:
                        setattr(product, attr, val)

            supplier__name = row['supplier__name']
            if supplier__name:
                supplier = \
                    Supplier.objects.get_or_create(name__iexact=supplier__name, defaults={'name': supplier__name})[
                        0]
                product.supplier = supplier

            try:
                product.save()
            except IntegrityError:
                pass  # todo what?
            else:
                products_count += 1
        if delete_file:
            os.remove(filepath)
    return products_count

And this is a view action:

@action(methods=['post'], detail=False)
def import_csv(self, request, pk=None) -> Response:
    csv_file = request.FILES['file']
    csv_import_files_dir = os.path.join('/tmp/project_imports/')
    csv_file_path = os.path.join(csv_import_files_dir, str(uuid.uuid4()))
    os.makedirs(csv_import_files_dir, exist_ok=True)
    with open(csv_file_path, 'wb') as f:
        f.write(csv_file.read())
    count = product_services.imports.ImportService.import_csv(csv_file_path, request.user)
    return Response({'imported': count})

Do you know where is the problem?

Milano
  • 18,048
  • 37
  • 153
  • 353
  • You are catching and ignoring database errors (`except IntegrityError`). Is an exception being raised and then ignored before you get the other error? – Andrew May 28 '21 at 14:59
  • Have you checked this https://stackoverflow.com/questions/21458387/transactionmanagementerror-you-cant-execute-queries-until-the-end-of-the-atom?rq=1 ? – Umair Mohammad May 28 '21 at 15:01

0 Answers0