OperationalError: cursor "_django_curs_<id>" does not exist

Viewed 13751

We have an online store web-app which is powered by django, postgresql and heroku.

For a specific campaign (you can think a campaign like a product to purchase), we have sold 10k+ copies successfully. Yet some of our users are encountered this error according to our Sentry reports. Common specification of these users is; none of them have address information before the purchase. Generally, users fill out address form right after registering. If they don't, they need to fill the form while purchasing the product and submit them together.

This is how the trace looks like:

OperationalError: cursor "_django_curs_140398688327424_146" does not exist

(66 additional frame(s) were not displayed)
...
  File "store/apps/store_main/templatetags/store_form_filters.py", line 31, in render_form
    return render_to_string('widgets/store_form_renderer.html', ctx)
  File "store/apps/store_main/templatetags/store_form_filters.py", line 20, in render_widget
    return render_to_string('widgets/store_widget_renderer.html', ctx)
  File "store/apps/store_main/widgets.py", line 40, in render
    attrs=attrs) + "<span class='js-select-support select-arrow'></span><div class='js-select-support select-arrow-space'><b></b></div>"

OperationalError: cursor "_django_curs_140398688327424_146" does not exist 

So another weird common thing, there are exception messages between sql queries before the failure. You can see it in the image below:

Exception while resolving variable

I'm adding it if they are somehow related. What may also be related is, the users who get this error are the users who tries to purchase the campaign right after a bulk mailing. So, extensive traffic might be the reason yet we are also not sure.

We asked Heroku about the problem since they are hosting the postgres, yet they do not have any clue either.

I know the formal reason of this error is trying to reach the cursor after a commit. Since it is destroyed after transaction, trying to reach it cause this error yet I don't see this in our scenario. We are not touching the cursor in any way. What am I missing? What may produce this error? How to prevent it? Any ideas would be appreciated.

3 Answers

If you're using django-pytest and have enabled the optimization --reuse-db and have made DB migrations between test runs you need to re-create the DB tables again.

pytest --create-db

Most likely you have forgotten to makemigrations and migrate them to the database. If you are sure you did make the migrations and running python manage.py makemigrations and python manage.py migrate will not find the changes you made then the database and models are not in sync. Sometimes this situation can be very frustrating if you have a big database. You will need to manually inspect your models.

To help out you can try this trick, which has been working for me.

  • Step 1 (delete all migrations from apps) I am going to assume you are using the unix terminal. run sudo rm -rv */migrations/*. This removes all the migrations files and caches.
  • Step 2 (make the migration folders in each app) run the command mkdir <app-folder>/migrations && touch <app-folder>/__init__.py. Replace with the name of the app that you have in the INSTALLED_APPS list in your default django settings file.
  • Step 3 (Make Migrations) Here we populate the migrations folders in each app with migration files. Run python manage.py makemigrations. Run the second command. python manage.py migrate --fake. We are using the --fake flag because the data already exists in the database and so we do not want to populate name database tables that are already there or you will be greeted with the already exists error

If this did not work, then you will need to temper with some additional fields on the database. such as the django_migrations or a similarly named table. This is not recommended as there are other database tables that depend on it such as the django_contenttypes and this will throw you in a chain of related tables that you will manually inspect which is very painful.

Related