Какое наилучшее решение для пула соединений с базой данных в python?

python mysql connection-pooling

40300 просмотра

8 ответа

Я разработал некоторые пользовательские классы, подобные DAO, для удовлетворения некоторых очень специфических требований для моего проекта, который является процессом на стороне сервера, который не работает в каких-либо рамках.

Решение отлично работает, за исключением того, что каждый раз, когда выполняется новый запрос, я открываю новое соединение через MySQLdb.connect.

Какое наилучшее решение «отбросить», чтобы переключить это на использование пула соединений в python? Я представляю себе что-то вроде решения DBCP для Java.

Процесс длительный и имеет много потоков, которые должны делать запросы, но не все в одно и то же время ... в частности, они выполняют довольно много работы до кратковременных очередей, выписывая кусок их результатов.

Отредактировано для добавления: после некоторого поиска я нашел anitpool.py, который выглядит приличным, но поскольку я относительно новичок в python, я думаю, я просто хочу убедиться, что я не пропущу более очевидное / более идиоматическое / лучшее решение.

Автор: John Источник Размещён: 17.05.2019 03:47

Ответы (8)


15 плюса

Решение

IMO, «более очевидное / более идиоматическое / лучшее решение» - использовать существующую ORM, а не изобретать DAO-подобные классы.

Мне кажется, что ORM более популярны, чем «сырые» SQL-соединения. Зачем? Поскольку Python является OO, а отображение SQL строки для объекта является абсолютно необходимым. Существует не так много случаев, когда вы имеете дело со строками SQL, которые не сопоставляются с объектами Python.

Я думаю, что SQLAlchemy или SQLObject (и связанный пул соединений) - более идиоматическое решение Pythonic.

Объединение в качестве отдельной функции не очень распространено, потому что чистый SQL (без сопоставления объектов) не очень популярен для сложных, длительных процессов, которые извлекают выгоду из пула соединений. Да, чистый SQL будет использован, но он всегда используется в более простых или более контролируемых приложениях , где объединение не является полезным.

Я думаю, у вас могут быть две альтернативы:

  1. Пересмотрите ваши классы, чтобы использовать SQLAlchemy или SQLObject. Хотя сначала это кажется болезненным [все, что работает впустую], вы должны иметь возможность использовать весь дизайн и мысли, а это просто упражнение в принятии широко используемого решения ORM и объединения.
  2. Создайте свой собственный простой пул соединений, используя описанный вами алгоритм - простой набор или список подключений, которые вы просматриваете.
Автор: S.Lott Размещён: 19.09.2008 02:13

22 плюса

В MySQL?

Я бы сказал, не беспокойтесь о пуле соединений. Они часто являются источником проблем, и с MySQL они не собираются приносить вам преимущество в производительности, на которое вы надеетесь. Эта дорога может быть предпринята с большим трудом - политически - потому что в этом пространстве так много размахивают ручным размахиванием и формулировкой учебника о преимуществах объединения пулов.

Пулы подключений - это просто мост между эпохой пост-Интернета приложений без состояния (например, HTTP-протокол) и предварительной эрой долговременных приложений пакетной обработки с сохранением состояния. Поскольку соединения были очень дорогими в предварительных веб-базах данных (поскольку никто не заботился слишком много о том, как долго было установлено соединение), пост-веб-приложения разработали эту схему пула соединений, так что каждый удар не повлек за собой огромные издержки обработки на РСУБД.

Поскольку MySQL - это больше RDBMS в веб-эпохе, соединения очень легкие и быстрые. Я написал много веб-приложений большого объема, которые вообще не используют пул соединений для MySQL.

Это осложнение, которое вам может пригодиться, если нет политического препятствия для преодоления.

Автор: mbac32768 Размещён: 19.09.2008 04:11

16 плюса

Оберните свой класс подключения.

Установите ограничение на количество подключений. Верните неиспользуемое соединение. Перехватитесь, чтобы освободить соединение.

Обновление: я помещаю что-то вроде этого в dbpool.py:

import sqlalchemy.pool as pool
import MySQLdb as mysql
mysql = pool.manage(mysql)
Автор: Chris Размещён: 19.09.2008 01:38

6 плюса

Старая нить, но для общего назначения (соединения или любой дорогой объект) я использую что-то вроде:

def pool(ctor, limit=None):
    local_pool = multiprocessing.Queue()
    n = multiprocesing.Value('i', 0)
    @contextlib.contextmanager
    def pooled(ctor=ctor, lpool=local_pool, n=n):
        # block iff at limit
        try: i = lpool.get(limit and n.value >= limit)
        except multiprocessing.queues.Empty:
            n.value += 1
            i = ctor()
        yield i
        lpool.put(i)
    return pooled

Конструкция лениво, имеет дополнительный предел и должна обобщаться на любой случай использования, о котором я могу думать. Конечно, это предполагает, что вам действительно нужен пул любого ресурса, который вы не можете использовать для многих современных SQL-подобных. Использование:

# in main:
my_pool = pool(lambda: do_something())
# in thread:
with my_pool() as my_obj:
    my_obj.do_something()

Это предполагает, что любой объект ctor создает, если необходимо, соответствующий деструктор (некоторые серверы не уничтожают объекты соединения, если они не закрыты явно).

Автор: metaperture Размещён: 14.07.2014 04:53

2 плюса

Я просто искал то же самое.

Я нашел pysqlpool и модуль пула sqlalchemy

Автор: Willie Размещён: 14.05.2009 05:41

2 плюса

Создание собственного пула подключений - идея BAD, если ваше приложение когда-либо решает начать многопоточность. Создание пула соединений для многопоточного приложения намного сложнее, чем одно для однопоточного приложения. В этом случае вы можете использовать что-то вроде PySQLPool.

Это также идея BAD использовать ORM, если вы ищете производительность.

Если вы будете иметь дело с огромными / тяжелыми базами данных, которые должны обрабатывать множество выборок, вставлять, обновлять и удалять одновременно, тогда вам понадобится производительность, а это означает, что вам понадобится специальный SQL, написанный для оптимизации поиска и время блокировки. С ORM у вас обычно нет такой гибкости.

Итак, в принципе, да, вы можете создать свой собственный пул соединений и использовать ORM, но только если вы уверены, что вам не понадобится что-то из того, что я только что описал.

Автор: flexo Размещён: 22.08.2011 10:05

1 плюс

Отвечая на старый поток, но в последний раз, когда я проверил, MySQL предлагает пул соединений в составе своих драйверов.

Вы можете проверить их на:

https://dev.mysql.com/doc/connector-python/en/connector-python-connection-pooling.html

Из TFA, Предполагая, что вы хотите явно открыть пул соединений (как указывал OP):

dbconfig = {  "database": "test", "user":"joe" }
cnxpool = mysql.connector.pooling.MySQLConnectionPool(pool_name = "mypool",pool_size = 3, **dbconfig)

После этого пул получает запрос через пул через функцию get_connection ().

cnx1 = cnxpool.get_connection()
cnx2 = cnxpool.get_connection()
Автор: kilokahn Размещён: 10.06.2017 05:32

0 плюса

Используйте DBUtils, простой и надежный.

pip install DBUtils

Автор: ospider Размещён: 11.11.2018 07:05
Вопросы из категории :
32x32