Search code examples
pythondjangopostgresqldjango-databasedjango-deployment

Query still running for django_migrations


I'm developing a django web app and i have notice something strange. The following query will stay in execution in the DB

SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations"

here the example from: select query_start,state_change,waiting,state,query from pg_stat_activity;

test6=> select query_start,state_change,waiting,state,query from pg_stat_activity;
          query_start          |         state_change          | waiting | state  |                                                                  query
-------------------------------+-------------------------------+---------+--------+--------------------------------------------------------------------------------------------------
 2017-06-21 16:02:21.926337+02 | 2017-06-21 16:02:21.926402+02 | f       | idle   | SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations"

untill stop the "runserver"

Current settings:

  • Django 1.11.2
  • PostgreSQL 9.2.17
  • Using Django ORM only
  • All migrations were applied
  • CONN_MAX_AGE setted in settings.py

Why Django doesn't close the connection after the query execution?


Solution

  • From the documentation, Django uses persistent connections:

    [...] each thread maintains its own connection

    The runserver command is itself a thread, and the SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations" simply represent the last query made on the connection, once the results has been returned, the state is left idle.

    If you try to execute a query once migrations are checked, in wsgi for example, that request would replace the one you are seeing.

    Hence, the runserver by default create a thread for each incoming request, so the connection made (in main thread) for checking migrations is never closed, by the doc:

    At the beginning of each request, Django closes the connection if it has reached its maximum age. If your database terminates idle connections after some time, you should set CONN_MAX_AGE to a lower value, so that Django doesn’t attempt to use a connection that has been terminated by the database server. (This problem may only affect very low traffic sites.)

    As you can read, the closing is made either by Postgres, or by Django on the next request. So either you configure postgres to kill the idle connections, or you can use the --nothreading on runserver to reuse the connection made by the main thread (warning: it highly affects performance).