В этом материале рассмотрим понятие пула соединений и особенности его реализации для базы данных PostgreSQL в Python с помощью Psycopg2.
Пул соединений — это кэшированные соединения с базой данных, которые создаются и поддерживаются таким образом, чтобы не было необходимости пересоздавать их для новых запросов.
Реализация и использование пула соединений в приложении Python, работающим с базой данных PostgreSQL, дает несколько преимуществ.
Основное — улучшение времени и производительности. Как известно, создание соединения с базой данных PostgreSQL — операция, потребляющая ресурсы и время. А с помощью пула можно уменьшить время запроса и ответа для приложений, работающих с базой данных в Python. Рассмотрим, как его реализовать.
В модуле psycopg2 есть 4 класса для управления пулом соединений. С их помощью можно легко создавать пул и управлять им. Как вариант, того же результата можно добиться с помощью реализации абстрактного класса.
Классы psycopg2 для управления пулом соединений
В модуле psycopg2 есть четыре класса для управления пулом соединений:
- AbstractConnectionPool.
- SimpleConnectionPool.
- ThreadedConnectionPool.
- PersistentConnectionPool.
Примечание:
SimpleConnectionPool
,ThreadedConnectionPool
иPersistentConnectionPool
являются подклассамиAbstractConnectionPool
и реализуют методы из него.
Рассмотрим каждый из них по отдельности.
AbstractConnectionPool
Это базовый класс, реализующий обобщенный код пула, основанный на ключе.
psycopg2.pool.AbstractConnectionPool(minconn, maxconn, *args, **kwargs)
AbstractConnectionPool — это абстрактный класс. Наследуемые должны реализовывать объявленные в нем методы. Если хотите создать собственную реализацию пула соединений, то нужно наследоваться от него и реализовать эти методы.
minconn
— это минимальное требуемое количество объектов соединения. *args
, *kwargs
— аргументы, которые нужны для метода connect()
, отвечающего за подключение к базе данных PostgreSQL.
SimpleConnectionPool
Это подкласс AbstractConnectionPool
, реализующий его методы. Его уже можно использовать для пула соединений.
Этот класс подходит только для однопоточных приложений. Это значит, что если вы хотите создать пул соединений с помощью этого класса, то его нельзя будет передавать между потоками.
Синтаксис:
psycopg2.pool.SimpleConnectionPool(minconn, maxconn, *args, **kwargs)
ThreadedConnectionPool
Он также является подклассом класса AbstractConnectionPool
и реализует его методы.
Этот класс используется в многопоточной среде, т.е. пул, созданный с помощью этого класса, можно разделить между несколькими потоками.
psycopg2.pool.ThreadedConnectionPool(minconn, maxconn, *args, **kwargs)
PersistentConnectionPool
Еще один подкласс AbstractConnectionPool
, реализующий его методы.
Этот класс используется в многопоточных приложениях с пулом, распределяющим постоянные соединения разным потокам.
Как и предполагает название, каждый поток получает одно соединение из пула. Таким образом, у одного потока может быть не больше одного соединения из пула.
Пул соединений генерирует ключ с помощью идентификатора потока. Это значит, что для каждого потока при вызовах соединение не меняется.
Примечание: этот класс преимущественно предназначен для взаимодействия с Zope и, вероятно, не подходит для обычных приложений.
Синтаксис:
psycopg2.pool.PersistentConnectionPool(minconn, maxconn, *args, **kwargs)
Посмотрим, как создать пул соединений.
Методы psycopg2 для управления пулом соединений
Следующие методы представлены в модуле Psycopg2 и используются для управления.
getconn(key=None)
— для получения доступного соединения из пула. Параметрkey
необязательный. При использовании этого параметраgetconn()
возвращает соединение, связанное с этим ключом. Key используется в классеPersistentConnectionPool
.putconn(connection, key=None, close=False)
— для возвращения соединения обратно в пул. Если параметрclose
равенTrue
, то соединение удаляется и из пула. Если при получении соединения был использован ключ, то его же нужно передать при возвращении соединения.closeall()
— закрывает все используемые соединения пула.
Создание пула соединений с помощью psycopg2
В этом примере используем SimpleConnectionPool
для создания пула. Перед этим стоит рассмотреть аргументы, которые требуются для работы.
Нужно указать минимальное и максимальное количество соединений, имя пользователя, пароль, хост и базу данных.
minconn
— это нижний лимит количества подключений.maxconn
— максимальное количество возможных подключений.*args
,**kwargs
— аргументы для методаconnect()
, необходимые для создания объекта соединений. Тут требуется указать имя хоста, пользователя, пароль, базу данных и порт.
Пример создания и управления пулом соединений PostgreSQL
Рассмотрим, как использовать класс SimpleConnectionPool
для создания и управления пулом соединений из Python.
import psycopg2
from psycopg2 import pool
try:
# Подключиться к существующей базе данных
postgresql_pool = psycopg2.pool.SimpleConnectionPool(1, 20,
user="postgres",
# пароль, который указали при установке PostgreSQL
password="1111",
host="127.0.0.1",
port="5432",
database="postgres_db")
if postgresql_pool:
print("Пул соединений создан успешно")
# Используйте getconn() для получения соединения из пула соединений.
connection = postgresql_pool.getconn()
if connection:
print("Соединение установлено")
cursor = connection.cursor()
cursor.execute("select * from mobile")
mobile_records = cursor.fetchall()
print ("Отображение строк с таблицы mobile")
for row in mobile_records:
print(row)
cursor.close()
# Используйте этот метод, чтобы отпустить объект соединения
# и отправить обратно в пул соединений
postgresql_pool.putconn(connection)
print("PostgreSQL соединение вернулось в пул")
except (Exception, psycopg2.DatabaseError) as error :
print ("Ошибка при подключении к PostgreSQL", error)
finally:
if postgresql_pool:
postgresql_pool.closeall
print("Пул соединений PostgreSQL закрыт")
Вывод:
Пул соединений создан успешно
Соединение установлено
Отображение строк с таблицы mobile
(1, 'IPhone 12', 800.0)
(2, 'Google Pixel 2', 900.0)
PostgreSQL соединение вернулось в пул
Пул соединений PostgreSQL закрыт
Разберем пример. В метод были переданы следующие значения:
- Minimum connection = 1. Это значит, что в момент создания пула создается как минимум одно соединение.
- Maximum connection = 20. Всего можно использовать 20 соединений с PostgreSQL.
- Другие параметры для подключения.
- Конструктор класса
SimpleConnectionPool
возвращает экземпляр пула. - С помощью
getconn()
делается запрос на подключение из пула - После этого выполняются операции в базе данных.
- И в конце закрываются все активные и пассивные объекты соединения для закрытия приложения.
Создание многопоточного пула соединений
Создадим пул соединений, который будет работать в многопоточной среде. Это можно сделать с помощью класса ThreadedConnectionPool
.
import psycopg2
from psycopg2 import pool
try:
# Подключиться к существующей базе данных
postgresql_pool = psycopg2.pool.ThreadedConnectionPool(5, 20,
user="postgres",
# пароль, который указали при установке PostgreSQL
password="1111",
host="127.0.0.1",
port="5432",
database="postgres_db")
if postgresql_pool:
print("Пул соединений создан успешно")
# Используйте getconn() для получения соединения из пула соединений.
connection = postgresql_pool.getconn()
if connection:
print("Соединение установлено")
cursor = connection.cursor()
cursor.execute("select * from mobile")
mobile_records = cursor.fetchall()
print ("Отображение строк с таблицы mobile")
for row in mobile_records:
print(row)
cursor.close()
# Используйте этот метод, чтобы отпустить объект соединения
# и отправить обратно в пул соединений
postgresql_pool.putconn(connection)
print("PostgreSQL соединение вернулось в пул")
except (Exception, psycopg2.DatabaseError) as error :
print ("Ошибка при подключении к PostgreSQL", error)
finally:
if postgresql_pool:
postgresql_pool.closeall
print("Пул соединений PostgreSQL закрыт")
Вывод будет таким же: