Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

An error occurred in the current transaction. You can't execute queries until the end of the 'atomic' block

Have read multiple sources for solutions such as Guaravs post (including all recommendations in the comments), and Alexander, to name a few, but still not able to fix the issue. The error comes when creating a database entry @ models.OrderItemTax.objects.create()

Using django 1.11.3 and MySQL 14.14

views.py **only partial code since the function is over 600 lines long.

def checkout_cart(request):
     try:
        item_to_group_keys = []
        promo_key = 'promo:' + str(request.user.id)

        with connection.cursor() as cursor:
            with transaction.atomic():
                // more code here...
                try:
                    with transaction.atomic(): // updated solution
                        event = ''
                        group = models.Group.objects.get(id=order_item.group.id)
                        now = timezone.now()
                        event_date = now.strftime('%Y-%m-%d')

                        try:
                            event = models.Event.objects.get(group_id=group.id, date=event_date)
                            try:
                                self_attendee = models.EventAttendee.objects.get(event=event,
                                                                                    user_id=request.user.id,
                                                                                    is_attending=True)
                            except:
                                self_attendee = models.EventAttendee.objects.create(event=event,
                                                                                    user_id=request.user.id,
                                                                                    is_attending=True)
                                self_attendee.save()
                        except models.Event.DoesNotExist:
                            event = models.Event.objects.create(group_id=group.id, date=event_date, planner_id=request.user.id)
                            todays_site_deal = models.SiteDeal.objects.get_deal()
                            if todays_site_deal is not None and todays_site_deal != '':
                                event.site_deal = todays_site_deal
                            event.save()

                            self_attendee = models.EventAttendee.objects.create(event=event, user_id=request.user.id, is_attending=True)
                            self_attendee.save()

                            initial_group_members = models.GroupMembership.objects.filter(group_id=group.id, status_id=1)
                            group_members = initial_group_members.exclude(user_id=request.user.id)

                            for gm in group_members:
                                userprofile = models.UserProfile.objects.get(user_id=gm.user_id)
                                attendee_request = models.EventAttendeeRequest.objects.create(event=event, user_id=gm.user_id)
                                attendee_request.status = models.EventRequestStatusOpt.objects.get(id=3)
                                attendee_request.save()
                                group_fn = gm.user.first_name
                                group_ln = gm.user.last_name
                                group_pn = userprofile.phone

                                if group_fn != '' and group_ln != '' and group_pn != '' and group_pn is not None:

                                    non_digits = re.compile(r'[^\d]+')
                                    group_pn = non_digits.sub('', group_pn)

                                    # request_hash = str(member_request.pk) + str(group_id) + str(int(round(time.time())))
                                    # request_hash = int(request_hash) ^ 0xABCEEFAB
                                    # member_request.hash = request_hash

                                    text_message = event.planner.first_name + " from your Cliiique " + event.group.name + " started shopping. Join today's event!"
                                    try:
                                        pn_check = client_lookup.phone_numbers.get(group_pn)

                                        if pn_check.phone_number is not None:  # if invalid, throws an exception
                                            # SMS
                                            # -------------------------------------------------
                                            message = client_rest.messages.create(
                                                body=text_message,
                                                to=group_pn,
                                                from_="+12132050074")
                                            # -------------------------------------------------

                                    except TwilioRestException as e:
                                        pass


                except: #group not in checkout, do not create event
                    pass

                # Get tax amount for each Item
                rate = Decimal('0.0950')
                oi_price = Decimal(order_item.op_price.strip(''))
                tax_amount = oi_price * rate
                oi_tax = models.OrderItemTax.objects.create(amount=tax_amount,
                                                            rate=rate,
                                                            order_item_id=order_item.pk)
                oi_tax.save()
     except IntegrityError:
        return HttpResponse("<strong>CODE #700: Fatal Transaction Error! Please contact customer service.</strong>")
like image 972
jsibs Avatar asked Jun 14 '18 21:06

jsibs


People also ask

Can't execute queries until the end of the atomic block?

You can't execute queries until the end of the 'atomic' block." is raised when you try to used a database connection after a database exception even those autocommit was set to false from the start. It should be up to the user how to handle the database exception and the transaction as autocommit was set to false.

What is atomic transaction Django?

Django provides a single API to control database transactions. Atomicity is the defining property of database transactions. atomic allows us to create a block of code within which the atomicity on the database is guaranteed. If the block of code is successfully completed, the changes are committed to the database.


Video Answer


1 Answers

From docs:

Avoid catching exceptions inside atomic!

Since the function had multiple nested try and excepts, I inserted another transaction.atomic() within a the try and except closest to where the error is occurring.

Per docs, have nested try and excepts could complicate the initial atomic. I found that placing the atomic (for a second time) helps. Hope this helps others facing a similar situation.

 try:
    item_to_group_keys = []
    promo_key = 'promo:' + str(request.user.id)

    with connection.cursor() as cursor:
        with transaction.atomic():
            // more code here...
            try:
                with transaction.atomic(): // **added second atomic**
                   //more code
            except:
                pass
 except IntegrityError:
like image 162
jsibs Avatar answered Nov 14 '22 21:11

jsibs