简体   繁体   中英

Django - PostgreSQL set statement_timeout

I'm using Django 1.10 and PostgreSQL DB. I'm trying to figure out whether I can set statement_timeout from Django. Seems like I can't do it the same way as for connect_timeout (in settings.py ):

DATABASES[DEFAULT]['OPTIONS'] = {
    'connect_timeout': float(os.getenv('DEFAULT_DB_OPTIONS_TIMEOUT', 5))
}

I saw something like this, but I can't find a way to verify it actually works:

DATABASES[DEFAULT]['OPTIONS'] = {
    'options': '-d statement_timeout=700'
}

I know I can set it directly from the DB like:

set statement_timeout=5000

but I'm looking for a way to do it from Django.

There is no other "Django" way of doing this. The Django way is to use your settings.py like you indicate, except your example is not quite right. It should be:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        ...
        'OPTIONS': {
            'options': '-c statement_timeout=5000',
            ...
        }
    }
}

The 'OPTIONS' dictionary is for arguments to the database connection string. The list of Postgres arguments can be found here . The options connection string argument allows you to specify command-line arguments for postgres. The -c option is explained here .

Note that the timeout is measured in milliseconds, so the 5000 above means 5 seconds.

I use Django 3.2.16 on Windows 11 then, I set '-c statement_timeout=5000' in OPTIONS and 'SET statement_timeout = 5000;' with cursor.execute() in settings.py as shown below:

# "settings.py"

from django.db import connection

# ...

DATABASES = {
    'default':{
        'ENGINE':'django.db.backends.postgresql',
        'NAME':'postgres',
        'USER':'postgres',
        'PASSWORD':'admin',
        'HOST':'localhost',
        'PORT':'5432',
        # 'ATOMIC_REQUESTS': True,
    },
    'OPTIONS': {
        'options': '-c statement_timeout=5000' # Here
     }
}

cursor = connection.cursor()
cursor.execute('SET statement_timeout = 5000;') # Here

Then, test view with cursor.execute('SELECT pg_sleep(10);') below runs without any errors because statement_timeout = 5000 in settings.py doesn't work in test view :

# "views.py"

from django.db import connection
from django.http import HttpResponse

def test(request):
    cursor = connection.cursor()
    cursor.execute('SELECT pg_sleep(10);')
    
    return HttpResponse("Test")

But, when setting statement_timeout = 5000 in test view as shown below:

# "views.py"

from django.db import connection
from django.http import HttpResponse

def test(request):
    cursor = connection.cursor()
    cursor.execute('SET statement_timeout = 5000;')
    cursor.execute('SELECT pg_sleep(10);')
    
    return HttpResponse("Test")

The error below occurs because statement_timeout = 5000 in test view works properly. * cursor.execute('SET statement_timeout = 5000;') only applies to test view rather than other views so you need to call cursor.execute('SET statement_timeout = 5000;') in each view if you want to apply cursor.execute('SET statement_timeout = 5000;') to each view:

django.db.utils.OperationalError: canceling statement due to statement timeout

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