在多线程环境中关闭Django ORM连接

u0sqgete  于 2022-09-21  发布在  Go
关注(0)|答案(2)|浏览(222)

我有以下代码在独立的脚本,这是使用Django orm(外Django)与多线程。

import threading 

MAX_THREADS = 30
semaphore = threading.Semaphore(value=MAX_THREADS)

books = Books.objects.all()
for book in books:
    book_id = book.id
    t = threading.Thread(target=process_book, args=[book_id])
    t.start()
    threads.append(t)

    for t in threads:
        t.join()

def process_book(book_id):
    semaphore.acquire()
    book = Books.objects.get(id=book_id)
    # Do some time taking stuff here
    book.save()
    semaphore.release()

一旦线程数达到postgres的MAX_CLIENT_CONN设置(默认为100),我在进一步调用时开始收到以下错误:

操作致命错误:剩余的连接插槽保留给非复制超级用户连接

对此进行研究后,我得到了使用pgbouncer这样的数据库池的解决方案,然而,这只会在连接可用之前暂停新连接,但在我遇到Django的查询wat超时之后再次延迟

/QUERY_WAIT_TIMEOUT服务器上的操作错误意外关闭了连接,这可能意味着服务器在处理请求之前或处理请求时异常终止。

我知道发生这种情况是因为线程没有关闭它们正在建立的数据库连接,但我不确定如何关闭orm调用连接?在上面的代码流中,我是否可以做一些不同的事情来减少连接数量?

我需要对单个示例执行GET操作才能更新它们,因为.update().save()不能处理查询集项目。

wd2eg0qa

wd2eg0qa1#

这将更新数据库中所有帐簿中的字段

for book in books:
    Books.objects.filter(id=book.id).bulk_update(book, ['field to update'])

更新每本书

def process_book(book_id):
    semaphore.acquire()
    book = get_object_or_404(Books, id=book_id).update(field)   # Do some time taking stuff here

    semaphore.release()
0lvr5msh

0lvr5msh2#

只需在线程结束时关闭数据库连接

from django import db

def process_book(book_id):
    semaphore.acquire()
    book = Books.objects.get(id=book_id)
    # Do some time taking stuff here
    book.save()
    semaphore.release()
    db.connections.close_all()

相关问题