Объединение соединений

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

В частности, для веб-приложений на стороне сервера пул соединений является стандартным способом поддержания в памяти «пула» активных соединений с базой данных, которые повторно используются при выполнении запросов.

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

Конфигурация пула соединений

Функция Engine, возвращаемая функцией create_engine(), в большинстве случаев имеет встроенный QueuePool, предварительно сконфигурированный с разумными настройками пулинга по умолчанию. Если вы читаете этот раздел только для того, чтобы узнать, как включить пулинг - поздравляю! Вы уже сделали это.

Наиболее распространенные параметры настройки QueuePool могут быть переданы непосредственно в create_engine() в качестве аргументов ключевых слов: pool_size, max_overflow, pool_recycle и pool_timeout. Например:

engine = create_engine(
    "postgresql+psycopg2://me@localhost/mydb", pool_size=20, max_overflow=0
)

Все реализации пула SQLAlchemy объединяет то, что ни одна из них не «предварительно создает» соединения - все реализации ждут до первого использования, прежде чем создать соединение. В этот момент, если не поступает дополнительных одновременных запросов на установку соединений, дополнительные соединения не создаются. Вот почему совершенно нормально для create_engine() по умолчанию использовать QueuePool размером пять без учета того, действительно ли приложению нужно пять соединений в очереди - пул вырастет до такого размера, только если приложение действительно использует пять соединений одновременно, и в этом случае использование небольшого пула является вполне подходящим поведением по умолчанию.

Реализации коммутационных пулов

Обычный способ использования пула другого типа с create_engine() - это использование аргумента poolclass. Этот аргумент принимает класс, импортированный из модуля sqlalchemy.pool, и обрабатывает детали создания пула за вас. Обычно пул соединений отключается, что можно сделать с помощью реализации NullPool:

from sqlalchemy.pool import NullPool

engine = create_engine(
    "postgresql+psycopg2://scott:tiger@localhost/test", poolclass=NullPool
)

Использование пользовательской функции подключения

Подробную информацию о различных процедурах настройки соединения см. в разделе Пользовательские аргументы DBAPI connect() / процедуры включения соединения.

Строительство бассейна

Чтобы использовать Pool самостоятельно, функция creator является единственным аргументом, который требуется, и передается первой, за которой следуют любые дополнительные опции:

import sqlalchemy.pool as pool
import psycopg2


def getconn():
    c = psycopg2.connect(user="ed", host="127.0.0.1", dbname="test")
    return c


mypool = pool.QueuePool(getconn, max_overflow=10, pool_size=5)

Затем соединения DBAPI могут быть получены из пула с помощью функции Pool.connect(). Возвращаемым значением этого метода является соединение DBAPI, содержащееся в прозрачном прокси:

# get a connection
conn = mypool.connect()

# use it
cursor_obj = conn.cursor()
cursor_obj.execute("select foo")

Цель прозрачного прокси - перехватить вызов close(), чтобы вместо закрытия соединения DBAPI оно было возвращено в пул:

# "close" the connection.  Returns
# it to the pool.
conn.close()

Прокси также возвращает содержащееся в нем DBAPI-соединение в пул при сборке мусора, хотя в Python это происходит не сразу (хотя это типично для cPython). Однако такое использование не рекомендуется и, в частности, не поддерживается с драйверами asyncio DBAPI.

Сброс при возврате

Пул включает в себя поведение «сброс при возврате», которое вызовет метод rollback() соединения DBAPI, когда соединение будет возвращено в пул. Это делается для того, чтобы из соединения было удалено любое существующее транзакционное состояние, которое включает не только незафиксированные данные, но и блокировки таблиц и строк. Для большинства DBAPI вызов rollback() не требует больших затрат, и если DBAPI уже завершила транзакцию, этот метод не должен работать.

Отключение сброса при возврате для нетранзакционных соединений

Для очень специфических случаев, когда это rollback() не полезно, например, при использовании соединения, настроенного на autocommit или при использовании базы данных, не имеющей возможностей ACID, например, движка MyISAM в MySQL, поведение сброса при возврате может быть отключено, что обычно делается по соображениям производительности. На это можно повлиять, используя параметр Pool.reset_on_return в Pool, который также доступен из create_engine() как create_engine.pool_reset_on_return, передавая значение None. Это показано в примере ниже в сочетании с параметром create_engine.isolation_level, установленным в AUTOCOMMIT:

non_acid_engine = create_engine(
    "mysql://scott:tiger@host/db",
    pool_reset_on_return=None,
    isolation_level="AUTOCOMMIT",
)

Приведенный выше движок фактически не будет выполнять ROLLBACK, когда соединения возвращаются в пул; поскольку AUTOCOMMIT включен, драйвер также не будет выполнять никакой операции BEGIN.

Пользовательские схемы сброса-возврата

«сброс при возврате», состоящий из одного rollback(), может быть недостаточным для некоторых случаев использования; в частности, приложения, использующие временные таблицы, могут пожелать, чтобы эти таблицы автоматически удалялись при регистрации соединения. Некоторые (но, конечно, не все) бэкенды включают функции, которые могут «сбрасывать» такие таблицы в рамках соединения с базой данных, что может быть желательным поведением для сброса пула соединений. Другие ресурсы сервера, такие как обработчики подготовленных операторов и кэши операторов на стороне сервера, могут сохраняться после процесса проверки, что может быть как желательным, так и нежелательным, в зависимости от специфики. Опять же, некоторые (но опять же не все) бэкенды могут предоставлять средства для сброса этого состояния. Два диалекта SQLAlchemy, в которых, как известно, есть такие схемы сброса, включают Microsoft SQL Server, где часто используется недокументированная, но широко известная хранимая процедура sp_reset_connection, и PostgreSQL, в котором есть хорошо документированная серия команд, включая DISCARD RESET, DEALLOCATE и UNLISTEN.

В следующем примере показано, как заменить сброс на возврат с помощью хранимой процедуры Microsoft SQL Server sp_reset_connection, используя крючок события PoolEvents.reset(). Параметр create_engine.pool_reset_on_return установлен в None, чтобы пользовательская схема могла полностью заменить поведение по умолчанию. Реализация пользовательского хука в любом случае вызывает .rollback(), поскольку обычно важно, чтобы собственное отслеживание DBAPI фиксации/отката оставалось согласованным с состоянием транзакции:

from sqlalchemy import create_engine
from sqlalchemy import event

mssql_engine = create_engine(
    "mssql+pyodbc://scott:tiger^5HHH@mssql2017:1433/test?driver=ODBC+Driver+17+for+SQL+Server",
    # disable default reset-on-return scheme
    pool_reset_on_return=None,
)


@event.listens_for(mssql_engine, "reset")
def _reset_mssql(dbapi_connection, connection_record, reset_state):
    if not reset_state.terminate_only:
        dbapi_connection.execute("{call sys.sp_reset_connection}")

    # so that the DBAPI itself knows that the connection has been
    # reset
    dbapi_connection.rollback()

Изменено в версии 2.0.0b3: Добавлены дополнительные аргументы состояния для события PoolEvents.reset() и дополнительно обеспечен вызов события для всех случаев «сброса», так что его можно использовать в качестве места для пользовательских обработчиков «сброса». Предыдущие схемы, использующие обработчик PoolEvents.checkin(), также остаются пригодными для использования.

Регистрация событий сброса при возврате

Ведение журнала для событий в бассейне, включая сброс при возврате, можно установить logging.DEBUG уровень журнала вместе с регистратором sqlalchemy.pool, или установив create_engine.echo_pool на "debug" при использовании create_engine():

>>> from sqlalchemy import create_engine
>>> engine = create_engine("postgresql://scott:tiger@localhost/test", echo_pool="debug")

Вышеуказанный пул покажет подробное протоколирование, включая сброс при возврате:

>>> c1 = engine.connect()
DEBUG sqlalchemy.pool.impl.QueuePool Created new connection <connection object ...>
DEBUG sqlalchemy.pool.impl.QueuePool Connection <connection object ...> checked out from pool
>>> c1.close()
DEBUG sqlalchemy.pool.impl.QueuePool Connection <connection object ...> being returned to pool
DEBUG sqlalchemy.pool.impl.QueuePool Connection <connection object ...> rollback-on-return

Мероприятия в бассейне

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

Работа с разъединениями

Пул соединений имеет возможность обновлять как отдельные соединения, так и весь набор соединений, устанавливая ранее установленные соединения как «недействительные». Распространенный случай использования - позволить пулу соединений изящно восстановиться, когда сервер базы данных был перезапущен, и все ранее установленные соединения больше не функционируют. Для этого существует два подхода.

Работа с разъединениями - пессимистично

Пессимистический подход заключается в выдаче тестового оператора для SQL-соединения в начале каждой проверки пула соединений, чтобы проверить, что соединение с базой данных все еще жизнеспособно. Реализация зависит от диалекта и использует либо специфический для DBAPI метод ping, либо простой SQL-оператор типа «SELECT 1», чтобы проверить соединение на жизнеспособность.

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

Пессимистическое тестирование соединений при проверке достижимо с помощью аргумента Pool.pre_ping, доступного из create_engine() через аргумент create_engine.pool_pre_ping:

engine = create_engine("mysql+pymysql://user:pw@host/db", pool_pre_ping=True)

Функция «pre ping» работает на основе каждого диалекта, либо вызывая специфический для DBAPI метод «ping», либо, если он недоступен, будет выдавать SQL, эквивалентный «SELECT 1», отлавливая любые ошибки и определяя ошибку как ситуацию «разъединения». Если проверка ping / ошибок определит, что соединение не может быть использовано, оно будет немедленно утилизировано, а все другие соединения в пуле, более старые, чем текущее время, будут аннулированы, так что при следующей проверке они также будут утилизированы перед использованием.

Если база данных все еще недоступна, когда выполняется «pre ping», то первоначальное подключение будет неудачным, и ошибка о невозможности подключения будет распространена нормально. В редкой ситуации, когда база данных доступна для подключения, но не может ответить на «ping», «pre_ping» будет пытаться до трех раз, прежде чем сдастся, распространяя последнюю полученную ошибку базы данных.

Важно отметить, что подход предварительного пинга не учитывает соединения, потерянные в середине транзакций или других операций SQL. Если база данных станет недоступной во время выполнения транзакции, транзакция будет потеряна и возникнет ошибка базы данных. Хотя объект Connection обнаружит ситуацию «разъединения» и переработает соединение, а также аннулирует остальной пул соединений, когда это произойдет, отдельная операция, при которой было вызвано исключение, будет потеряна, и приложению придется либо отказаться от операции, либо повторить всю транзакцию заново. Если движок настроен с использованием автокоммит-соединений на уровне DBAPI, как описано в Установка уровней изоляции транзакций, включая DBAPI Autocommit, соединение может быть переподключено прозрачно в середине операции с использованием событий. Пример смотрите в разделе Как автоматически «повторить» выполнение запроса?.

Для диалектов, которые используют «SELECT 1» и ловят ошибки для обнаружения разъединения, тест на разъединение может быть дополнен новыми сообщениями об ошибках, специфичными для бэкенда, с помощью хука DialectEvents.handle_error().

Пользовательский / Наследие Пессимистический пинг

До добавления create_engine.pool_pre_ping подход «предварительного пинга» исторически выполнялся вручную с использованием события движка ConnectionEvents.engine_connect(). Наиболее распространенный рецепт для этого приведен ниже, для справки, если приложение уже использует такой рецепт, или если требуется особое поведение:

from sqlalchemy import exc
from sqlalchemy import event
from sqlalchemy import select

some_engine = create_engine(...)


@event.listens_for(some_engine, "engine_connect")
def ping_connection(connection, branch):
    if branch:
        # this parameter is always False as of SQLAlchemy 2.0,
        # but is still accepted by the event hook.  In 1.x versions
        # of SQLAlchemy, "branched" connections should be skipped.
        return

    try:
        # run a SELECT 1.   use a core select() so that
        # the SELECT of a scalar value without a table is
        # appropriately formatted for the backend
        connection.scalar(select(1))
    except exc.DBAPIError as err:
        # catch SQLAlchemy's DBAPIError, which is a wrapper
        # for the DBAPI's exception.  It includes a .connection_invalidated
        # attribute which specifies if this connection is a "disconnect"
        # condition, which is based on inspection of the original exception
        # by the dialect in use.
        if err.connection_invalidated:
            # run the same SELECT again - the connection will re-validate
            # itself and establish a new connection.  The disconnect detection
            # here also causes the whole connection pool to be invalidated
            # so that all stale connections are discarded.
            connection.scalar(select(1))
        else:
            raise

Приведенный выше рецепт имеет то преимущество, что мы используем возможности SQLAlchemy для обнаружения тех исключений DBAPI, которые, как известно, указывают на ситуацию «разъединения», а также способность объекта Engine правильно аннулировать текущий пул соединений при возникновении этого условия и позволить текущему Connection заново валидироваться на новое соединение DBAPI.

Работа с разъединением - оптимистично

Когда пессимистическая обработка не используется, а также когда база данных выключается и/или перезапускается в середине периода использования соединения в транзакции, другой подход к работе с устаревшими / закрытыми соединениями заключается в том, чтобы позволить SQLAlchemy обрабатывать разъединения по мере их возникновения, в этот момент все соединения в пуле аннулируются, то есть они считаются устаревшими и будут обновлены при следующей проверке. Это поведение предполагает, что Pool используется в сочетании с Engine. Engine имеет логику, которая может обнаруживать события разъединения и автоматически обновлять пул.

Когда Connection пытается использовать соединение DBAPI и возникает исключение, соответствующее событию «разъединение», соединение аннулируется. Затем Connection вызывает метод Pool.recreate(), эффективно аннулируя все соединения, не проверенные в данный момент, чтобы при следующей проверке они были заменены новыми. Этот поток проиллюстрирован в примере кода ниже:

from sqlalchemy import create_engine, exc

e = create_engine(...)
c = e.connect()

try:
    # suppose the database has been restarted.
    c.execute(text("SELECT * FROM table"))
    c.close()
except exc.DBAPIError as e:
    # an exception is raised, Connection is invalidated.
    if e.connection_invalidated:
        print("Connection was invalidated!")

# after the invalidate event, a new connection
# starts with a new Pool
c = e.connect()
c.execute(text("SELECT * FROM table"))

Приведенный выше пример иллюстрирует, что для обновления пула не требуется специального вмешательства, которое продолжается в обычном режиме после обнаружения события разъединения. Тем не менее, возникает одно исключение базы данных на каждое соединение, которое используется во время возникновения события недоступности базы данных. В типичном веб-приложении, использующем ORM Session, вышеописанное условие будет соответствовать одному запросу, который завершится ошибкой 500, после чего веб-приложение продолжит работу в нормальном режиме. Таким образом, данный подход является «оптимистичным», так как частые перезагрузки базы данных не предвидятся.

Настройка утилизации пула

Дополнительным параметром, который может дополнить «оптимистичный» подход, является параметр recycle пула. Этот параметр не позволяет пулу использовать конкретное соединение, возраст которого истек, и подходит для бэкендов баз данных, таких как MySQL, которые автоматически закрывают соединения, которые устарели после определенного периода времени:

from sqlalchemy import create_engine

e = create_engine("mysql+mysqldb://scott:tiger@localhost/test", pool_recycle=3600)

Выше, любое соединение DBAPI, которое было открыто более одного часа, будет аннулировано и заменено при следующей проверке. Обратите внимание, что аннулирование только происходит во время проверки - не для любых соединений, которые находятся в состоянии проверки. pool_recycle является функцией самого Pool, независимо от того, используется ли Engine.

Подробнее об инвалидизации

Pool предоставляет услуги «аннулирования соединения», которые позволяют как явное аннулирование соединения, так и автоматическое аннулирование в ответ на условия, которые делают соединение непригодным для использования.

«Недействительность» означает, что конкретное DBAPI-соединение удаляется из пула и отбрасывается. Метод .close() вызывается на этом соединении, если не ясно, что само соединение может быть не закрыто, однако если этот метод не сработает, исключение регистрируется, но операция все равно продолжается.

Если используется Engine, метод Connection.invalidate() является обычной точкой входа для явного аннулирования. Другие условия, при которых соединение DBAPI может быть признано недействительным, включают:

  • исключение DBAPI, такое как OperationalError, возникающее при вызове метода типа connection.execute(), определяется как указание на так называемое состояние «разъединения». Поскольку Python DBAPI не предоставляет стандартной системы для определения природы исключения, все диалекты SQLAlchemy включают систему под названием is_disconnect(), которая изучает содержимое объекта исключения, включая строковое сообщение и любые потенциальные коды ошибок, включенные в него, чтобы определить, указывает ли это исключение на то, что соединение больше не может использоваться. Если это так, то вызывается метод _ConnectionFairy.invalidate() и соединение DBAPI отбрасывается.

  • Когда соединение возвращается в пул, и вызов методов connection.rollback() или connection.commit(), как диктуется поведением пула «reset on return», вызывает исключение. Будет сделана последняя попытка вызвать .close() на соединении, после чего оно будет отброшено.

  • Когда слушатель, реализующий PoolEvents.checkout(), вызывает исключение DisconnectionError, указывающее на то, что соединение не может быть использовано и необходимо предпринять новую попытку соединения.

Все возникающие недействительности будут вызывать событие PoolEvents.invalidate().

Поддержка новых кодов ошибок базы данных для сценариев разъединения

Каждый диалект SQLAlchemy включает в себя процедуру is_disconnect(), которая вызывается всякий раз, когда встречается исключение DBAPI. Объект исключения DBAPI передается в этот метод, где эвристика, специфичная для диалекта, определяет, указывает ли полученный код ошибки на то, что соединение с базой данных было «отключено» или находится в непригодном для использования состоянии, которое указывает на необходимость его утилизации. Применяемая здесь эвристика может быть настроена с помощью крючка событий DialectEvents.handle_error(), который обычно устанавливается через принадлежащий ему объект Engine. Используя этот хук, все возникающие ошибки передаются вместе с контекстным объектом, известным как ExceptionContext. Пользовательские крючки событий могут контролировать, должна ли конкретная ошибка считаться ситуацией «разъединения» или нет, а также должно ли это разъединение приводить к аннулированию всего пула соединений или нет.

Например, чтобы добавить поддержку для рассмотрения кодов ошибок Oracle DPY-1001 и DPY-4011 в качестве кодов отключения, примените обработчик события к движку после создания:

import re

from sqlalchemy import create_engine

engine = create_engine("oracle://scott:tiger@dnsname")


@event.listens_for(engine, "handle_error")
def handle_exception(context: ExceptionContext) -> None:
    if not context.is_disconnect and re.match(
        r"^(?:DPI-1001|DPI-4011)", str(context.original_exception)
    ):
        context.is_disconnect = True

    return None

Приведенная выше функция обработки ошибок будет вызываться для всех возникающих ошибок Oracle, включая те, которые возникают при использовании функции pool pre ping для тех бэкендов, которые полагаются на обработку ошибок разъединения (новое в 2.0).

Использование FIFO против LIFO

Класс QueuePool имеет флаг QueuePool.use_lifo, который также может быть доступен из create_engine() через флаг create_engine.pool_use_lifo. Установка этого флага в значение True приводит к тому, что поведение «очереди» пула становится поведением «стека», например, последнее соединение, возвращенное в пул, будет первым, которое будет использовано при следующем запросе. В отличие от давнего поведения пула по принципу «первым пришел - первым ушел», который создает эффект круговой очереди, последовательно используя каждое соединение в пуле, режим lifo позволяет лишним соединениям оставаться в пуле незадействованными, позволяя схемам тайм-аута на стороне сервера закрывать эти соединения. Разница между FIFO и LIFO заключается в том, желательно ли для пула поддерживать полный набор соединений, готовых к работе, даже в периоды простоя:

engine = create_engine("postgreql://", pool_use_lifo=True, pool_pre_ping=True)

Выше мы также использовали флаг create_engine.pool_pre_ping, чтобы соединения, закрываемые со стороны сервера, изящно обрабатывались пулом соединений и заменялись новым соединением.

Обратите внимание, что флаг применяется только при использовании QueuePool.

Добавлено в версии 1.3.

Использование пулов соединений с многопроцессорной обработкой или os.fork()

Очень важно, чтобы при использовании пула соединений и, соответственно, при использовании Engine, созданного через create_engine(), пул соединений не был общим для вилочного процесса. TCP-соединения представлены в виде дескрипторов файлов, которые обычно работают через границы процессов, что означает, что это приведет к одновременному доступу к дескриптору файла от имени двух или более совершенно независимых состояний интерпретатора Python.

В зависимости от специфики драйвера и ОС, проблемы, возникающие здесь, варьируются от нерабочих соединений до сокетных соединений, которые используются несколькими процессами одновременно, что приводит к нарушению обмена сообщениями (последний случай, как правило, наиболее распространен).

Объект SQLAlchemy Engine относится к пулу соединений существующих соединений базы данных. Поэтому, когда этот объект реплицируется в дочерний процесс, цель состоит в том, чтобы гарантировать, что никакие соединения с базой данных не будут перенесены. Для этого существует три общих подхода:

  1. Отключите объединение соединений с помощью NullPool. Это наиболее упрощенная, одноразовая система, которая не позволяет Engine использовать любое соединение более одного раза:

    from sqlalchemy.pool import NullPool
    
    engine = create_engine("mysql+mysqldb://user:pass@host/dbname", poolclass=NullPool)
  2. Вызовите Engine.dispose() на любом данном Engine, передав параметру Engine.dispose.close значение False, в фазе инициализации дочернего процесса. Это делается для того, чтобы новый процесс не трогал соединения родительского процесса, а начинал с новых соединений. Это рекомендуемый подход:

    from multiprocessing import Pool
    
    engine = create_engine("mysql+mysqldb://user:pass@host/dbname")
    
    
    def run_in_process(some_data_record):
        with engine.connect() as conn:
            conn.execute(text("..."))
    
    
    def initializer():
        """ensure the parent proc's database connections are not touched
        in the new connection pool"""
        engine.dispose(close=False)
    
    
    with Pool(10, initializer=initializer) as p:
        p.map(run_in_process, data)

    Добавлено в версии 1.4.33: Добавлен параметр Engine.dispose.close, позволяющий заменить пул соединений в дочернем процессе без вмешательства в соединения, используемые родительским процессом.

  3. Вызовите Engine.dispose() непосредственно перед созданием дочернего процесса. Это также приведет к тому, что дочерний процесс начнет работу с новым пулом соединений, при этом родительские соединения не будут переданы дочернему процессу:

    engine = create_engine("mysql://user:pass@host/dbname")
    
    
    def run_in_process():
        with engine.connect() as conn:
            conn.execute(text("..."))
    
    
    # before process starts, ensure engine.dispose() is called
    engine.dispose()
    p = Process(target=run_in_process)
    p.start()
  4. К пулу соединений можно применить обработчик событий, который проверяет наличие соединений, совместно используемых через границы процессов, и аннулирует их:

    from sqlalchemy import event
    from sqlalchemy import exc
    import os
    
    engine = create_engine("...")
    
    
    @event.listens_for(engine, "connect")
    def connect(dbapi_connection, connection_record):
        connection_record.info["pid"] = os.getpid()
    
    
    @event.listens_for(engine, "checkout")
    def checkout(dbapi_connection, connection_record, connection_proxy):
        pid = os.getpid()
        if connection_record.info["pid"] != pid:
            connection_record.dbapi_connection = connection_proxy.dbapi_connection = None
            raise exc.DisconnectionError(
                "Connection record belongs to pid %s, "
                "attempting to check out in pid %s" % (connection_record.info["pid"], pid)
            )

    Выше мы использовали подход, аналогичный описанному в Работа с разъединениями - пессимистично, чтобы рассматривать соединение DBAPI, возникшее в другом родительском процессе, как «недействительное» соединение, заставляя пул переработать запись соединения для создания нового соединения.

Приведенные выше стратегии подходят для случая, когда Engine разделяется между процессами. Приведенных выше шагов недостаточно для случая совместного использования конкретного Connection через границу процесса; лучше сохранить область видимости конкретного Connection локальной для одного процесса (и потока). Кроме того, не поддерживается обмен любым видом текущего транзакционного состояния непосредственно через границу процесса, например, объектом ORM Session, который начал транзакцию и ссылается на активные экземпляры Connection; опять же, предпочтительнее создавать новые объекты Session в новых процессах.

Использование экземпляра пула напрямую

Реализация пула может быть использована напрямую без движка. Это может быть использовано в приложениях, которые просто хотят использовать поведение пула без всех остальных возможностей SQLAlchemy. В приведенном ниже примере пул по умолчанию для диалекта MySQLdb получен с помощью create_pool_from_url():

from sqlalchemy import create_pool_from_url

my_pool = create_pool_from_url(
    "mysql+mysqldb://", max_overflow=5, pool_size=5, pre_ping=True
)

con = my_pool.connect()
# use the connection
...
# then close it
con.close()

Если тип создаваемого пула не указан, будет использован пул по умолчанию для данного диалекта. Чтобы указать его напрямую, можно использовать аргумент poolclass, как в следующем примере:

from sqlalchemy import create_pool_from_url
from sqlalchemy import NullPool

my_pool = create_pool_from_url("mysql+mysqldb://", poolclass=NullPool)

Документация API - Доступные реализации пулов

Object Name Description

_ConnectionFairy

Проксирует соединение DBAPI и обеспечивает поддержку возврата по ссылке.

_ConnectionRecord

Сохраняет позицию в пуле соединений, которая ссылается на объединенное соединение.

AssertionPool

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

ConnectionPoolEntry

Интерфейс для объекта, который поддерживает индивидуальное соединение с базой данных от имени экземпляра Pool.

ManagesConnection

Общая база для двух интерфейсов управления соединениями PoolProxiedConnection и ConnectionPoolEntry.

NullPool

Пул, который не объединяет соединения.

Pool

Абстрактный базовый класс для пулов соединений.

PoolProxiedConnection

Адаптер, подобный соединению, для соединения PEP 249 DBAPI, который включает дополнительные методы, специфичные для реализации Pool.

QueuePool

Pool, который накладывает ограничение на количество открытых соединений.

SingletonThreadPool

Пул, поддерживающий одно соединение на поток.

StaticPool

Пул из ровно одного соединения, используемый для всех запросов.

class sqlalchemy.pool.Pool

Абстрактный базовый класс для пулов соединений.

Классная подпись

класс sqlalchemy.pool.Pool (sqlalchemy.log.Identified, sqlalchemy.event.registry.EventTarget)

method sqlalchemy.pool.Pool.__init__(creator: Union[_CreatorFnType, _CreatorWRecFnType], recycle: int = -1, echo: log._EchoFlagType = None, logging_name: Optional[str] = None, reset_on_return: _ResetStyleArgType = True, events: Optional[List[Tuple[_ListenerFnType, str]]] = None, dialect: Optional[Union[_ConnDialect, Dialect]] = None, pre_ping: bool = False, _dispatch: Optional[_DispatchCommon[Pool]] = None)

Постройте бассейн.

Параметры:
  • creator – вызываемая функция, которая возвращает объект соединения DB-API. Функция будет вызвана с параметрами.

  • recycle – Если установлено значение, отличное от -1, количество секунд между перезагрузками соединения, что означает, что при проверке, если этот таймаут превышен, соединение будет закрыто и заменено вновь открытым соединением. По умолчанию значение равно -1.

  • logging_name – Строковый идентификатор, который будет использоваться в поле «name» записей журнала, создаваемых в логгере «sqlalchemy.pool». По умолчанию это шестнадцатеричная строка идентификатора объекта.

  • echo – если True, пул соединений будет записывать в журнал информационные данные, например, когда соединения аннулируются, а также когда соединения восстанавливаются, в обработчик журнала по умолчанию, который по умолчанию имеет значение sys.stdout для вывода. Если задана строка "debug", то в журнал будут записываться выходы и регистрации пула. Параметр Pool.echo также может быть установлен из вызова create_engine() с помощью параметра create_engine.echo_pool. … см. также:: Настройка ведения журнала - более подробную информацию о том, как настроить ведение журнала.

  • reset_on_return – Определяет шаги, которые следует предпринять для соединений, возвращаемых в пул, которые не были обработаны Connection. Доступно из create_engine() через параметр create_engine.pool_reset_on_return. Pool.reset_on_return может иметь любое из этих значений: * "rollback" - вызвать rollback() на соединении, чтобы освободить блокировки и ресурсы транзакции. Это значение по умолчанию. В подавляющем большинстве случаев следует оставить это значение установленным. * "commit" - вызвать commit() на соединении, чтобы освободить блокировки и ресурсы транзакции. Коммит здесь может быть желателен для баз данных, которые кэшируют планы запросов, если выполняется коммит, например, Microsoft SQL Server. Однако это значение более опасно, чем „rollback“, поскольку любые изменения данных, присутствующие в транзакции, фиксируются безоговорочно. * None - ничего не делать на соединении. Эта настройка может быть уместна, если база данных / DBAPI постоянно работает в режиме «autocommit», или если пользовательский обработчик сброса установлен с помощью обработчика события PoolEvents.reset(). * True - то же самое, что и «откат», здесь для обратной совместимости. * False - то же, что и None, здесь для обратной совместимости. Для дальнейшей настройки сброса при возврате можно использовать крючок события PoolEvents.reset(), который может выполнить любое действие соединения при сбросе. … см. также:: Сброс при возврате PoolEvents.reset()

  • events – список из двух кортежей, каждый из которых имеет форму (callable, target), который будет передан в listen() при построении. Предоставляется здесь для того, чтобы слушатели событий могли быть назначены через create_engine() до применения слушателей на уровне диалекта.

  • dialectDialect, который будет выполнять работу по вызову rollback(), close() или commit() на соединениях DBAPI. Если параметр опущен, то используется встроенный диалект «заглушка». Приложения, использующие create_engine(), не должны использовать этот параметр, так как он обрабатывается стратегией создания движка.

  • pre_ping – если True, пул будет отправлять «ping» (обычно «SELECT 1», но это зависит от диалекта) на соединение при проверке, чтобы проверить, живо ли соединение или нет. Если нет, соединение прозрачно переподключается, и в случае успеха все другие соединения пула, установленные до этой временной метки, аннулируются. Требуется, чтобы также был передан диалект для интерпретации ошибки разъединения. … версия добавлена:: 1.2

method sqlalchemy.pool.Pool.connect() PoolProxiedConnection

Возвращает соединение DBAPI из пула.

Соединение инструментируется таким образом, что при вызове его метода close() соединение будет возвращено в пул.

method sqlalchemy.pool.Pool.dispose() None

Утилизируйте этот бассейн.

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

См.также

Pool.recreate()

method sqlalchemy.pool.Pool.recreate() Pool

Возвращает новый Pool, того же класса, что и этот, и сконфигурированный с идентичными аргументами создания.

Этот метод используется в сочетании с dispose() для закрытия всего Pool и создания нового на его месте.

class sqlalchemy.pool.QueuePool

Pool, который накладывает ограничение на количество открытых соединений.

QueuePool - это реализация пула по умолчанию, используемая для всех объектов Engine, если только диалект SQLite не используется с базой данных :memory:.

Классная подпись

класс sqlalchemy.pool.QueuePool (sqlalchemy.pool.base.Pool)

method sqlalchemy.pool.QueuePool.__init__(creator: Union[_CreatorFnType, _CreatorWRecFnType], pool_size: int = 5, max_overflow: int = 10, timeout: float = 30.0, use_lifo: bool = False, **kw: Any)

Создайте пул очередей (QueuePool).

Параметры:
  • creator – вызываемая функция, которая возвращает объект соединения DB-API, такой же, как и Pool.creator.

  • pool_size – Размер пула, который будет поддерживаться, по умолчанию 5. Это наибольшее количество соединений, которое будет постоянно храниться в пуле. Обратите внимание, что пул начинается с отсутствия соединений; после запроса этого количества соединений, это количество соединений останется. pool_size может быть установлено в 0, чтобы указать отсутствие ограничений на размер; чтобы отключить пул, используйте вместо этого NullPool.

  • max_overflow – Максимальный размер переполнения пула. Когда количество проверенных соединений достигает размера, установленного в pool_size, дополнительные соединения будут возвращены до этого предела. Когда эти дополнительные соединения возвращаются в пул, они отсоединяются и отбрасываются. Отсюда следует, что общее количество одновременных соединений, которое допускает пул, равно pool_size + max_overflow, а общее количество «спящих» соединений, которое допускает пул, равно pool_size. max_overflow может быть установлено в -1, чтобы указать отсутствие ограничения переполнения; общее количество одновременных соединений не будет ограничено. По умолчанию установлено значение 10.

  • timeout – Количество секунд, которое необходимо выждать, прежде чем отказаться от возврата соединения. По умолчанию равно 30,0. Это может быть число с плавающей запятой, но оно зависит от ограничений функций времени Python, которые могут быть ненадежными в десятках миллисекунд.

  • use_lifo – использовать LIFO (last-in-first-out) при извлечении соединений вместо FIFO (first-in-first-out). Используя LIFO, схема тайм-аута на стороне сервера может уменьшить количество соединений, используемых в непиковые периоды использования. При планировании тайм-аутов на стороне сервера убедитесь, что используется стратегия рециркуляции или предварительного пинга для изящной обработки устаревших соединений. … версия добавлена:: 1.3 .. seealso:: Использование FIFO против LIFO Работа с разъединениями

  • **kw – Другие аргументы ключевых слов, включая Pool.recycle, Pool.echo, Pool.reset_on_return и другие, передаются конструктору Pool.

method sqlalchemy.pool.QueuePool.dispose() None

Утилизируйте этот бассейн.

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

См.также

Pool.recreate()

method sqlalchemy.pool.QueuePool.recreate() QueuePool

Возвращает новый Pool, того же класса, что и этот, и сконфигурированный с идентичными аргументами создания.

Этот метод используется в сочетании с dispose() для закрытия всего Pool и создания нового на его месте.

class sqlalchemy.pool.SingletonThreadPool

Пул, поддерживающий одно соединение на поток.

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

Предупреждение

SingletonThreadPool будет вызывать .close() на произвольных соединениях, существующих за пределами размера, установленного pool_size, например, если используется больше уникальных идентификаторов потоков, чем указано в pool_size. Эта очистка недетерминирована и не чувствительна к тому, используются ли в данный момент соединения, связанные с этими идентификаторами потоков.

SingletonThreadPool может быть улучшен в будущем выпуске, однако в текущем состоянии он обычно используется только для тестовых сценариев с использованием базы данных SQLite :memory: и не рекомендуется для производственного использования.

Параметры те же, что и в Pool, а также:

Параметры:

pool_size – Количество потоков, в которых необходимо поддерживать соединения одновременно. По умолчанию равно пяти.

SingletonThreadPool используется диалектом SQLite автоматически, когда используется база данных на основе памяти. См. SQLite.

Классная подпись

класс sqlalchemy.pool.SingletonThreadPool (sqlalchemy.pool.base.Pool)

method sqlalchemy.pool.SingletonThreadPool.connect() PoolProxiedConnection

Возвращает соединение DBAPI из пула.

Соединение инструментируется таким образом, что при вызове его метода close() соединение будет возвращено в пул.

method sqlalchemy.pool.SingletonThreadPool.dispose() None

Утилизируйте этот бассейн.

method sqlalchemy.pool.SingletonThreadPool.recreate() SingletonThreadPool

Возвращает новый Pool, того же класса, что и этот, и сконфигурированный с идентичными аргументами создания.

Этот метод используется в сочетании с dispose() для закрытия всего Pool и создания нового на его месте.

class sqlalchemy.pool.AssertionPool

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

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

Классная подпись

класс sqlalchemy.pool.AssertionPool (sqlalchemy.pool.base.Pool)

method sqlalchemy.pool.AssertionPool.dispose() None

Утилизируйте этот бассейн.

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

См.также

Pool.recreate()

method sqlalchemy.pool.AssertionPool.recreate() AssertionPool

Возвращает новый Pool, того же класса, что и этот, и сконфигурированный с идентичными аргументами создания.

Этот метод используется в сочетании с dispose() для закрытия всего Pool и создания нового на его месте.

class sqlalchemy.pool.NullPool

Пул, который не объединяет соединения.

Вместо этого он буквально открывает и закрывает базовое соединение DB-API при каждом открытии/закрытии соединения.

Функции, связанные с переподключением, такие как recycle и аннулирование соединения, не поддерживаются этой реализацией Pool, поскольку никакие соединения не сохраняются постоянно.

Классная подпись

класс sqlalchemy.pool.NullPool (sqlalchemy.pool.base.Pool)

method sqlalchemy.pool.NullPool.dispose() None

Утилизируйте этот бассейн.

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

См.также

Pool.recreate()

method sqlalchemy.pool.NullPool.recreate() NullPool

Возвращает новый Pool, того же класса, что и этот, и сконфигурированный с идентичными аргументами создания.

Этот метод используется в сочетании с dispose() для закрытия всего Pool и создания нового на его месте.

class sqlalchemy.pool.StaticPool

Пул из ровно одного соединения, используемый для всех запросов.

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

Классная подпись

класс sqlalchemy.pool.StaticPool (sqlalchemy.pool.base.Pool)

method sqlalchemy.pool.StaticPool.dispose() None

Утилизируйте этот бассейн.

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

См.также

Pool.recreate()

method sqlalchemy.pool.StaticPool.recreate() StaticPool

Возвращает новый Pool, того же класса, что и этот, и сконфигурированный с идентичными аргументами создания.

Этот метод используется в сочетании с dispose() для закрытия всего Pool и создания нового на его месте.

class sqlalchemy.pool.ManagesConnection

Общая база для двух интерфейсов управления соединениями PoolProxiedConnection и ConnectionPoolEntry.

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

Добавлено в версии 2.0.

attribute sqlalchemy.pool.ManagesConnection.dbapi_connection: Optional[DBAPIConnection]

Ссылка на фактическое отслеживаемое соединение DBAPI.

Это PEP 249-совместимый объект, который для традиционных диалектов в стиле sync предоставляется сторонней реализацией DBAPI. Для диалектов asyncio реализация обычно представляет собой объект адаптера, предоставляемый самим диалектом SQLAlchemy; базовый объект asyncio доступен через атрибут ManagesConnection.driver_connection.

Интерфейс SQLAlchemy для соединения DBAPI основан на объекте протокола DBAPIConnection.

attribute sqlalchemy.pool.ManagesConnection.driver_connection: Optional[Any]

Объект соединения «уровня драйвера», используемый Python DBAPI или драйвером базы данных.

Для традиционных реализаций DBAPI PEP 249 этот объект будет тем же объектом, что и объект ManagesConnection.dbapi_connection. Для драйвера базы данных asyncio, это будет конечный объект «соединения», используемый этим драйвером, такой как объект asyncpg.Connection, который не будет иметь стандартных методов pep-249.

Добавлено в версии 1.4.24.

attribute sqlalchemy.pool.ManagesConnection.info

Информационный словарь, связанный с базовым соединением DBAPI, на которое ссылается данный экземпляр ManagesConnection, позволяющий ассоциировать с соединением данные, определяемые пользователем.

Данные в этом словаре сохраняются в течение всего времени существования самого соединения DBAPI, включая все проверки и выходы из пула. Когда соединение аннулируется и заменяется новым, этот словарь очищается.

Для экземпляра PoolProxiedConnection, который не связан с ConnectionPoolEntry, например, если он отсоединен, атрибут возвращает словарь, локальный для этого ConnectionPoolEntry. Поэтому атрибут ManagesConnection.info всегда будет предоставлять словарь Python.

method sqlalchemy.pool.ManagesConnection.invalidate(e: Optional[BaseException] = None, soft: bool = False) None

Пометить управляемое соединение как недействительное.

Параметры:
  • e – объект исключения, указывающий на причину недействительности.

  • soft – если True, соединение не закрывается; вместо этого оно будет повторно использовано при следующей проверке.

attribute sqlalchemy.pool.ManagesConnection.record_info

Постоянный информационный словарь, связанный с этим ManagesConnection.

В отличие от словаря ManagesConnection.info, срок жизни этого словаря равен сроку жизни ConnectionPoolEntry, которому он принадлежит; поэтому этот словарь будет сохраняться при повторных подключениях и аннулировании соединения для конкретной записи в пуле соединений.

Для экземпляра PoolProxiedConnection, который не связан с ConnectionPoolEntry, например, если он отсоединен, атрибут возвращает None. В отличие от словаря ManagesConnection.info, который никогда не является None.

См.также

ManagesConnection.info

class sqlalchemy.pool.ConnectionPoolEntry

Интерфейс для объекта, который поддерживает индивидуальное соединение с базой данных от имени экземпляра Pool.

Объект ConnectionPoolEntry представляет собой долгосрочное обслуживание конкретного соединения для пула, включая истечение срока действия или аннулирование этого соединения для замены его новым, которое будет продолжать обслуживаться тем же экземпляром ConnectionPoolEntry. По сравнению с PoolProxiedConnection, который является краткосрочным менеджером соединений на каждую проверку, этот объект действует в течение всего срока жизни определенного «слота» в пуле соединений.

Объект ConnectionPoolEntry в основном виден публичному коду API, когда он доставляется к крючкам событий пула соединений, таким как PoolEvents.connect() и PoolEvents.checkout().

Добавлено в версии 2.0: ConnectionPoolEntry предоставляет публичный интерфейс для внутреннего класса _ConnectionRecord.

method sqlalchemy.pool.ConnectionPoolEntry.close() None

Закрыть соединение DBAPI, управляемое этой записью пула соединений.

attribute sqlalchemy.pool.ConnectionPoolEntry.dbapi_connection: Optional[DBAPIConnection]

Ссылка на фактическое отслеживаемое соединение DBAPI.

Это PEP 249-совместимый объект, который для традиционных диалектов в стиле sync предоставляется сторонней реализацией DBAPI. Для диалектов asyncio реализация обычно представляет собой объект адаптера, предоставляемый самим диалектом SQLAlchemy; базовый объект asyncio доступен через атрибут ManagesConnection.driver_connection.

Интерфейс SQLAlchemy для соединения DBAPI основан на объекте протокола DBAPIConnection.

attribute sqlalchemy.pool.ConnectionPoolEntry.driver_connection: Optional[Any]

Объект соединения «уровня драйвера», используемый Python DBAPI или драйвером базы данных.

Для традиционных реализаций DBAPI PEP 249 этот объект будет тем же объектом, что и объект ManagesConnection.dbapi_connection. Для драйвера базы данных asyncio, это будет конечный объект «соединения», используемый этим драйвером, такой как объект asyncpg.Connection, который не будет иметь стандартных методов pep-249.

Добавлено в версии 1.4.24.

attribute sqlalchemy.pool.ConnectionPoolEntry.in_use

Возвращает True соединение в настоящее время проверено

attribute sqlalchemy.pool.ConnectionPoolEntry.info

наследуется от ManagesConnection.info атрибута ManagesConnection

Информационный словарь, связанный с базовым соединением DBAPI, на которое ссылается данный экземпляр ManagesConnection, позволяющий ассоциировать с соединением данные, определяемые пользователем.

Данные в этом словаре сохраняются в течение всего времени существования самого соединения DBAPI, включая все проверки и выходы из пула. Когда соединение аннулируется и заменяется новым, этот словарь очищается.

Для экземпляра PoolProxiedConnection, который не связан с ConnectionPoolEntry, например, если он отсоединен, атрибут возвращает словарь, локальный для этого ConnectionPoolEntry. Поэтому атрибут ManagesConnection.info всегда будет предоставлять словарь Python.

method sqlalchemy.pool.ConnectionPoolEntry.invalidate(e: Optional[BaseException] = None, soft: bool = False) None

наследуется от ManagesConnection.invalidate() метода ManagesConnection

Пометить управляемое соединение как недействительное.

Параметры:
  • e – объект исключения, указывающий на причину недействительности.

  • soft – если True, соединение не закрывается; вместо этого оно будет повторно использовано при следующей проверке.

attribute sqlalchemy.pool.ConnectionPoolEntry.record_info

наследуется от ManagesConnection.record_info атрибута ManagesConnection

Постоянный информационный словарь, связанный с этим ManagesConnection.

В отличие от словаря ManagesConnection.info, срок жизни этого словаря равен сроку жизни ConnectionPoolEntry, которому он принадлежит; поэтому этот словарь будет сохраняться при повторных подключениях и аннулировании соединения для конкретной записи в пуле соединений.

Для экземпляра PoolProxiedConnection, который не связан с ConnectionPoolEntry, например, если он отсоединен, атрибут возвращает None. В отличие от словаря ManagesConnection.info, который никогда не является None.

См.также

ManagesConnection.info

class sqlalchemy.pool.PoolProxiedConnection

Адаптер, подобный соединению, для соединения PEP 249 DBAPI, который включает дополнительные методы, специфичные для реализации Pool.

PoolProxiedConnection является публичным интерфейсом для внутреннего объекта реализации _ConnectionFairy; пользователи, знакомые с _ConnectionFairy, могут считать этот объект эквивалентным.

Добавлено в версии 2.0: PoolProxiedConnection предоставляет публичный интерфейс для внутреннего класса _ConnectionFairy.

method sqlalchemy.pool.PoolProxiedConnection.close() None

Отпустите это соединение обратно в пул.

Метод PoolProxiedConnection.close() затеняет метод PEP 249 .close(), изменяя его поведение, чтобы вместо этого release вернуть проксированное соединение обратно в пул соединений.

При передаче в пул, остается ли соединение «открытым» и сохраняется в пуле в процессе Python, а не закрывается и удаляется из процесса Python, зависит от используемой реализации пула, его конфигурации и текущего состояния.

attribute sqlalchemy.pool.PoolProxiedConnection.dbapi_connection: Optional[DBAPIConnection]

Ссылка на фактическое отслеживаемое соединение DBAPI.

Это PEP 249-совместимый объект, который для традиционных диалектов в стиле sync предоставляется сторонней реализацией DBAPI. Для диалектов asyncio реализация обычно представляет собой объект адаптера, предоставляемый самим диалектом SQLAlchemy; базовый объект asyncio доступен через атрибут ManagesConnection.driver_connection.

Интерфейс SQLAlchemy для соединения DBAPI основан на объекте протокола DBAPIConnection.

method sqlalchemy.pool.PoolProxiedConnection.detach() None

Отделите это соединение от его Пула.

Это означает, что соединение больше не будет возвращаться в пул при закрытии, а будет буквально закрыто. Связанное соединение ConnectionPoolEntry деассоциируется с этим соединением DBAPI.

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

attribute sqlalchemy.pool.PoolProxiedConnection.driver_connection: Optional[Any]

Объект соединения «уровня драйвера», используемый Python DBAPI или драйвером базы данных.

Для традиционных реализаций DBAPI PEP 249 этот объект будет тем же объектом, что и объект ManagesConnection.dbapi_connection. Для драйвера базы данных asyncio, это будет конечный объект «соединения», используемый этим драйвером, такой как объект asyncpg.Connection, который не будет иметь стандартных методов pep-249.

Добавлено в версии 1.4.24.

attribute sqlalchemy.pool.PoolProxiedConnection.info

наследуется от ManagesConnection.info атрибута ManagesConnection

Информационный словарь, связанный с базовым соединением DBAPI, на которое ссылается данный экземпляр ManagesConnection, позволяющий ассоциировать с соединением данные, определяемые пользователем.

Данные в этом словаре сохраняются в течение всего времени существования самого соединения DBAPI, включая все проверки и выходы из пула. Когда соединение аннулируется и заменяется новым, этот словарь очищается.

Для экземпляра PoolProxiedConnection, который не связан с ConnectionPoolEntry, например, если он отсоединен, атрибут возвращает словарь, локальный для этого ConnectionPoolEntry. Поэтому атрибут ManagesConnection.info всегда будет предоставлять словарь Python.

method sqlalchemy.pool.PoolProxiedConnection.invalidate(e: Optional[BaseException] = None, soft: bool = False) None

наследуется от ManagesConnection.invalidate() метода ManagesConnection

Пометить управляемое соединение как недействительное.

Параметры:
  • e – объект исключения, указывающий на причину недействительности.

  • soft – если True, соединение не закрывается; вместо этого оно будет повторно использовано при следующей проверке.

attribute sqlalchemy.pool.PoolProxiedConnection.is_detached

Возвращает True, если этот PoolProxiedConnection отсоединен от своего пула.

attribute sqlalchemy.pool.PoolProxiedConnection.is_valid

Возвращает True, если этот PoolProxiedConnection все еще ссылается на активное DBAPI-соединение.

attribute sqlalchemy.pool.PoolProxiedConnection.record_info

наследуется от ManagesConnection.record_info атрибута ManagesConnection

Постоянный информационный словарь, связанный с этим ManagesConnection.

В отличие от словаря ManagesConnection.info, срок жизни этого словаря равен сроку жизни ConnectionPoolEntry, которому он принадлежит; поэтому этот словарь будет сохраняться при повторных подключениях и аннулировании соединения для конкретной записи в пуле соединений.

Для экземпляра PoolProxiedConnection, который не связан с ConnectionPoolEntry, например, если он отсоединен, атрибут возвращает None. В отличие от словаря ManagesConnection.info, который никогда не является None.

См.также

ManagesConnection.info

class sqlalchemy.pool._ConnectionFairy

Проксирует соединение DBAPI и обеспечивает поддержку возврата по ссылке.

Это внутренний объект, используемый реализацией Pool для обеспечения управления контекстом DBAPI-соединения, предоставляемого этим Pool. Публичный интерфейс этого класса описывается классом PoolProxiedConnection. Подробности публичного API см. в этом классе.

Название «фея» обусловлено тем, что время жизни объекта _ConnectionFairy преходяще, так как оно длится только в течение времени, пока конкретное DBAPI-соединение проверяется из пула, и, кроме того, как прозрачный прокси, он в основном невидим.

Классная подпись

класс sqlalchemy.pool._ConnectionFairy (sqlalchemy.pool.base.PoolProxiedConnection)

class sqlalchemy.pool._ConnectionRecord

Сохраняет позицию в пуле соединений, которая ссылается на объединенное соединение.

Это внутренний объект, используемый реализацией Pool для обеспечения управления контекстом DBAPI-соединения, поддерживаемого этим Pool. Публичный интерфейс этого класса описан в классе ConnectionPoolEntry. Подробности публичного API см. в этом классе.

Классная подпись

класс sqlalchemy.pool._ConnectionRecord (sqlalchemy.pool.base.ConnectionPoolEntry)

Вернуться на верх