Закрытие соединений 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()