File "/usr/local/lib/python3.7/dist-packages/psycopg2/__init__.py", line 126, in connect conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
django.db.utils.OperationalError: FATAL: remaining connection slots are reserved for non-replication superuser connections
根据 Postgres 文档,当 Django 与 Postgres DB 建立的连接数量超过默认连接限制时,就会发生此错误。
#settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'xxxxx',
'USER': 'xxxxx',
'PASSWORD':'xxxxx',
'HOST':'localhost',
'PORT':'5432',
}
我相信这是由于 Django 框架不进行数据库池而发生的。查看 Django 文档(https://docs.djangoproject.com/en/3.2/ref/databases/#transaction-pooling-and-server-side-cursors)我可以找到对用户 pgBouncer 的建议(http: //www.pgbouncer.org/)来处理这个问题。
这是一个使用线程和中间件的 Django PostgreSQL 解决方案。
数据库视图 您需要在数据库中创建一个视图 格式:应用程序_视图名称 我称我的为“configuration_terminate_idle_connections”
SELECT row_number() OVER (PARTITION BY true::boolean) AS id,
pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE
datname = 'database_name'
AND pid <> pg_backend_pid()
AND state = 'idle'
AND extract(epoch from (current_timestamp - query_start)) > 15*60;
型号
class terminate_idle_connections(models.Model):
pg_terminate_backend = models.BooleanField(default=True)
class Meta:
ordering = ['id']
managed = False
db_table = 'appname_terminate_idle_connections'
verbose_name_plural = "Database Terminate Idle Connections"
Admin(通过/admin手动运行)
class terminate_idle_connectionsView(admin.ModelAdmin):
list_display = ('id', 'pg_terminate_backend')
admin.site.register(terminate_idle_connections,terminate_idle_connectionsView)
设置.py 设置为你想要的
DB_MAX_CONNECTIONS = 700
DB_MAX_IDLE_CONNECTIONS = 150
中间件(提交请求时运行它) 我在 my_project_folder/middleware 中调用了我的“DbConnections.py”,与 settings.py 文件位于同一位置 完整文件路径:“my_project_folder/middleware/DbConnections.py”
from django.conf import settings
from appname.models import *
class DbConnections:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
return response
# PROCESSED BEFORE THE REQUESTED VIEW FUNCTION OR CLASS
def process_view(self, request, view_func, view_args, view_kwargs):
if settings.DEBUG: print("\nRemove idle Connections")
dbConection= database_activity.objects.all()
dbConectionCountAll= dbConection.count()
dbConectionCountIdle= dbConection.filter(state="idle").count()
if settings.DEBUG: print(" - Allowed Connections:",settings.DB_MAX_CONNECTIONS, "Actual Connections:",dbConectionCountAll)
if settings.DEBUG: print(" - Allowed Idle Connections:",settings.DB_MAX_IDLE_CONNECTIONS, "Actual Idle Connections:",dbConectionCountIdle)
if dbConectionCountAll >= settings.DB_MAX_CONNECTIONS or dbConectionCountIdle >= settings.DB_MAX_IDLE_CONNECTIONS:
terminateIdelConections = terminate_idle_connections.objects.all()
if settings.DEBUG: print("\n - Terminated Connections:", terminateIdelConections.count(),"\n")
设置中间件
MIDDLEWARE = [
'my_project_folder.Middleware.DbConnections.DbConnections',
'django.middleware.security.SecurityMiddleware',
...
]
查看线程(在计时器上运行) 在您的应用程序views.py文件中:
import threading
from django.conf import settings
from appname.models import *
def removeIdleDbConnections():
threading.Timer(900, removeIdleDbConnections).start()
# REMOVE IDLE CONNECTIONS
try:
dbConection= database_activity.objects.all()
dbConectionCountAll= database_activity.objects.all().count()
dbConectionCountIdle= database_activity.objects.filter(state="idle").count()
if dbConectionCountAll >= settings.DB_MAX_CONNECTIONS or dbConectionCountIdle >= settings.DB_MAX_IDLE_CONNECTIONS:
terminateIdelConections = terminate_idle_connections.objects.all()
if settings.DEBUG: print("Terminated Connections:", terminateIdelConections.count())
except:
pass
removeIdleDbConnections()
我在使用 Postgresql 数据库的 Django 项目中使用
concurrent
时遇到了类似的问题。我总是耗尽连接(要么与你有相同的操作错误,要么有一些变化)。
django-db-connection-pool
。它对我来说是开箱即用的,似乎解决了 django 中缺少数据库池的问题。
只需安装软件包:
pip install django-db-connection-pool[postgresql]
将
settings.py
中的后端引擎替换为
DATABASES = {
'default': {
'ENGINE': 'dj_db_conn_pool.backends.postgresql'
}
}
如果需要,您还可以使用
POOL_OPTIONS
添加一些选项(请参阅包文档)。