简体   繁体   English

Django - PostgreSQL 设置语句超时

[英]Django - PostgreSQL set statement_timeout

I'm using Django 1.10 and PostgreSQL DB.我正在使用 Django 1.10 和 PostgreSQL 数据库。 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 ):我想弄清楚我是否可以从 Django 设置statement_timeout 。似乎我不能像connect_timeout一样(在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.但我正在寻找一种从 Django 开始的方法。

There is no other "Django" way of doing this.没有其他“Django”方法可以做到这一点。 The Django way is to use your settings.py like you indicate, except your example is not quite right. Django 方法是像您指示的那样使用您的settings.py ,除了您的示例不太正确。 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. 'OPTIONS' 字典用于 arguments 到数据库连接字符串。 The list of Postgres arguments can be found here .可以在此处找到 Postgres arguments 的列表。 The options connection string argument allows you to specify command-line arguments for postgres. options连接字符串参数允许您为 postgres 指定命令行 arguments。 The -c option is explained here . -c选项在这里解释。

Note that the timeout is measured in milliseconds, so the 5000 above means 5 seconds.注意超时是以毫秒为单位的,所以上面的5000表示 5 秒。

I use Django 3.2.16 on Windows 11 then, I set '-c statement_timeout=5000' in OPTIONS and 'SET statement_timeout = 5000;'我在Windows 11上使用Django 3.2.16然后,我在OPTIONS中设置'-c statement_timeout=5000''SET statement_timeout = 5000;' with cursor.execute() in settings.py as shown below:settings.py中使用cursor.execute()如下所示:

# "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 :然后,下面的cursor.execute('SELECT pg_sleep(10);') test视图运行没有任何错误,因为settings.py中的statement_timeout = 5000test视图中不起作用:

# "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:但是,当在test视图中设置statement_timeout = 5000时,如下所示:

# "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.出现以下错误是因为test视图中的statement_timeout = 5000工作正常。 * 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: * cursor.execute('SET statement_timeout = 5000;')只适用于test视图而不适用于其他视图,因此如果要应用cursor.execute('SET statement_timeout = 5000;') ,则需要在每个视图中调用cursor.execute('SET statement_timeout = 5000;') cursor.execute('SET statement_timeout = 5000;')每个视图:

django.db.utils.OperationalError: canceling statement due to statement timeout django.db.utils.OperationalError: 由于语句超时取消语句

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM