Закрытие соединений django ORM в многопоточной среде

У меня есть следующий код в отдельном скрипте, который использует 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()

Когда количество потоков достигает MAX_CLIENT_CONN настройки postgres (которая по умолчанию равна 100), я начинаю получать следующую ошибку при дальнейших вызовах:

operationalError at FATAL: оставшиеся слоты подключения зарезервированы для не реплицирующихся соединений суперпользователя

Исследуя это, я пришел к решению использовать пулер базы данных, например pgbouncer, Однако это только задерживает новые соединения, пока соединения не станут доступны, но снова после тайм-аута запроса django я попадаю в

OperationalError at / query_wait_timeout сервер закрыл соединение соединение неожиданно Это, вероятно, означает, что сервер прервался до или во время обработки запроса.

Я понимаю, что это происходит потому, что потоки не закрывают соединения с БД, которые они создают, но я не уверен, как вообще закрывать соединения при вызове Orm? Есть ли что-то, что я мог бы сделать по-другому в вышеприведенном потоке кода, чтобы уменьшить количество соединений?

Мне нужно сделать get для отдельных экземпляров, чтобы обновить их, потому что .update() или .save() не работают с элементами queryset.

это обновляет поле во всех книгах в базе данных

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()
Вернуться на верх