PostgreSQL

Support for the PostgreSQL database.

The following table summarizes current support levels for database release versions.

Поддерживаемые версии PostgreSQL.

Support type

Versions

Fully tested in CI

9.6, 10, 11, 12, 13, 14

Normal support

9.6+

Best effort

9+

DBAPI Support

The following dialect/DBAPI options are available. Please refer to individual DBAPI sections for connect information.

Последовательности/СЕРИАЛ/ИДЕНТИЧНОСТЬ

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

Чтобы указать конкретную именованную последовательность, которая будет использоваться для генерации первичного ключа, используйте конструкцию Sequence():

Table(
    "sometable",
    metadata,
    Column(
        "id", Integer, Sequence("some_id_seq", start=1), primary_key=True
    )
)

Когда SQLAlchemy выпускает один оператор INSERT, чтобы выполнить контракт о наличии «идентификатора последней вставки», в оператор INSERT добавляется предложение RETURNING, которое определяет столбцы первичного ключа, которые должны быть возвращены после завершения оператора. Функция RETURNING работает только при использовании PostgreSQL 8.2 или более поздней версии. В качестве запасного варианта последовательность, заданная явно или неявно через SERIAL, предварительно выполняется независимо, а возвращаемое значение используется в последующей вставке. Обратите внимание, что когда конструкция insert() выполняется с использованием семантики «executemany», функциональность «последний вставленный идентификатор» не применяется; ни предложение RETURNING не выдается, ни последовательность предварительно не выполняется в этом случае.

Колонки IDENTITY в PostgreSQL 10 и выше

PostgreSQL 10 и выше имеет новую функцию IDENTITY, которая заменяет использование SERIAL. Конструкция Identity в Column может быть использована для управления его поведением:

from sqlalchemy import Table, Column, MetaData, Integer, Computed

metadata = MetaData()

data = Table(
    "data",
    metadata,
    Column(
        'id', Integer, Identity(start=42, cycle=True), primary_key=True
    ),
    Column('data', String)
)

CREATE TABLE для вышеуказанного объекта Table будет иметь вид:

CREATE TABLE data (
    id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 42 CYCLE),
    data VARCHAR,
    PRIMARY KEY (id)
)

Изменено в версии 1.4: Добавлена конструкция Identity в Column для указания опции автоинкрементного столбца.

Примечание

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

from sqlalchemy.schema import CreateColumn
from sqlalchemy.ext.compiler import compiles


@compiles(CreateColumn, 'postgresql')
def use_identity(element, compiler, **kw):
    text = compiler.visit_create_column(element, **kw)
    text = text.replace(
        "SERIAL", "INT GENERATED BY DEFAULT AS IDENTITY"
     )
    return text

Используя вышеизложенное, можно составить таблицу следующего вида:

t = Table(
    't', m,
    Column('id', Integer, primary_key=True),
    Column('data', String)
)

Будет генерироваться на резервной базе данных как:

CREATE TABLE t (
    id INT GENERATED BY DEFAULT AS IDENTITY,
    data VARCHAR,
    PRIMARY KEY (id)
)

Курсоры на стороне сервера

Поддержка курсора на стороне сервера доступна для диалектов psycopg2, asyncpg и может быть доступна в других диалектах.

Курсоры на стороне сервера включаются на основе каждого запроса с помощью опции выполнения соединения Connection.execution_options.stream_results:

with engine.connect() as conn:
    result = conn.execution_options(stream_results=True).execute(text("select * from table"))

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

Не рекомендуется, начиная с версии 1.4: Флаг server_side_cursors на уровне диалекта устарел и будет удален в одном из будущих выпусков. Для поддержки небуферизованных курсоров используйте опцию выполнения Connection.stream_results.

Уровень изоляции транзакций

Большинство диалектов SQLAlchemy поддерживают установку уровня изоляции транзакций с помощью параметра create_engine.isolation_level на уровне create_engine(), а на уровне Connection с помощью параметра Connection.execution_options.isolation_level.

Для диалектов PostgreSQL эта возможность работает либо с использованием специфичных для DBAPI функций, таких как флаги уровня изоляции psycopg2, которые встраивают установку уровня изоляции в строку с оператором "BEGIN", либо для DBAPI без прямой поддержки путем выдачи SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL <level> перед оператором "BEGIN", выдаваемым DBAPI. Для специального уровня изоляции AUTOCOMMIT используются специфические для DBAPI методы, которые обычно представляют собой флаг .autocommit на объекте соединения DBAPI.

Чтобы установить уровень изоляции с помощью create_engine():

engine = create_engine(
    "postgresql+pg8000://scott:tiger@localhost/test",
    isolation_level = "REPEATABLE READ"
)

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

with engine.connect() as conn:
    conn = conn.execution_options(
        isolation_level="REPEATABLE READ"
    )
    with conn.begin():
        # ... work with transaction

Существует также больше вариантов конфигураций уровня изоляции, например, объекты «sub-engine», связанные с основным Engine, в каждом из которых применяются различные настройки уровня изоляции. См. обсуждение в Установка уровней изоляции транзакций, включая DBAPI Autocommit для справки.

Допустимые значения для isolation_level в большинстве диалектов PostgreSQL включают:

  • READ COMMITTED

  • READ UNCOMMITTED

  • REPEATABLE READ

  • SERIALIZABLE

  • AUTOCOMMIT

Настройка ТОЛЬКО ДЛЯ ЧТЕНИЯ / ОТМЕНА

Большинство диалектов PostgreSQL поддерживают установку характеристик транзакции «READ ONLY» и «DEFERRABLE», что является дополнением к установке уровня изоляции. Эти два атрибута могут быть установлены как вместе с уровнем изоляции, так и независимо от него путем передачи флагов postgresql_readonly и postgresql_deferrable с помощью Connection.execution_options(). Приведенный ниже пример иллюстрирует передачу уровня изоляции "SERIALIZABLE" одновременно с установкой «ТОЛЬКО ЧТЕНИЕ» и «РАЗРЕШЕНО»:

with engine.connect() as conn:
    conn = conn.execution_options(
        isolation_level="SERIALIZABLE",
        postgresql_readonly=True,
        postgresql_deferrable=True
    )
    with conn.begin():
        #  ... work with transaction

Обратите внимание, что некоторые DBAPI, такие как asyncpg, поддерживают только «readonly» с изоляцией SERIALIZABLE.

Добавлено в версии 1.4: добавлена поддержка опций выполнения postgresql_readonly и postgresql_deferrable.

Временная таблица / сброс ресурсов для пула соединений

Реализация пула соединений QueuePool, используемая объектом SQLAlchemy Engine, включает поведение reset on return, которое будет вызывать метод DBAPI .rollback(), когда соединения возвращаются в пул. Хотя этот откат очищает непосредственное состояние, использованное предыдущей транзакцией, он не охватывает более широкий диапазон состояния на уровне сессии, включая временные таблицы, а также другие состояния сервера, такие как обработчики подготовленных операторов и кэши операторов. База данных PostgreSQL содержит множество команд, которые могут быть использованы для сброса этого состояния, включая DISCARD, RESET, DEALLOCATE и UNLISTEN.

Чтобы установить одну или несколько этих команд в качестве средства выполнения сброса при возврате, можно использовать крючок события PoolEvents.reset(), как показано в примере ниже. Реализация завершает выполняющиеся транзакции, а также удаляет временные таблицы с помощью команд CLOSE, RESET и DISCARD; см. документацию PostgreSQL для получения информации о том, что делает каждая из этих команд.

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

from sqlalchemy import create_engine
from sqlalchemy import event

postgresql_engine = create_engine(
    "postgresql+pyscopg2://scott:tiger@hostname/dbname",

    # disable default reset-on-return scheme
    pool_reset_on_return=None,
)


@event.listens_for(postgresql_engine, "reset")
def _reset_postgresql(dbapi_connection, connection_record, reset_state):
    if not reset_state.terminate_only:
        dbapi_connection.execute("CLOSE ALL")
        dbapi_connection.execute("RESET ALL")
        dbapi_connection.execute("DISCARD TEMP")

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

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

Настройка альтернативных путей поиска в Connect

Переменная PostgreSQL search_path относится к списку имен схем, на которые будут неявно ссылаться при ссылке на определенную таблицу или другой объект в операторе SQL. Как подробно описано в следующем разделе Интроспекция таблиц удаленных схем и поиск_пути в PostgreSQL, SQLAlchemy в целом организована вокруг концепции сохранения значения этой переменной по умолчанию public, однако для того, чтобы она была установлена на любое произвольное имя или имена при автоматическом использовании соединений, команда «SET SESSION search_path» может быть вызвана для всех соединений в пуле с помощью следующего обработчика событий, как обсуждалось в Установка схемы по умолчанию для новых подключений:

from sqlalchemy import event
from sqlalchemy import create_engine

engine = create_engine("postgresql+psycopg2://scott:tiger@host/dbname")

@event.listens_for(engine, "connect", insert=True)
def set_search_path(dbapi_connection, connection_record):
    existing_autocommit = dbapi_connection.autocommit
    dbapi_connection.autocommit = True
    cursor = dbapi_connection.cursor()
    cursor.execute("SET SESSION search_path='%s'" % schema_name)
    cursor.close()
    dbapi_connection.autocommit = existing_autocommit

Причина, по которой рецепт усложнен использованием атрибута DBAPI .autocommit, заключается в том, что когда вызывается директива SET SESSION search_path, она вызывается вне рамок любой транзакции и поэтому не будет возвращена при откате соединения DBAPI.

Интроспекция таблиц удаленных схем и поиск_пути в PostgreSQL

Обобщение лучших практик раздела

сохранить переменную search_path установленной по умолчанию public, без каких-либо других имен схем. Для других имен схем задавайте их явно в определениях Table. Альтернативно, опция postgresql_ignore_search_path заставит все отраженные объекты Table иметь установленный атрибут Table.schema.

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

Что касается таблиц, на которые эти Table объекты ссылаются через иностранный язык

По умолчанию диалект PostgreSQL имитирует поведение, поощряемое собственной встроенной процедурой PostgreSQL pg_get_constraintdef(). Эта функция возвращает образец определения для конкретного языка

test=> CREATE TABLE test_schema.referred(id INTEGER PRIMARY KEY);
CREATE TABLE
test=> CREATE TABLE referring(
test(>         id INTEGER PRIMARY KEY,
test(>         referred_id INTEGER REFERENCES test_schema.referred(id));
CREATE TABLE
test=> SET search_path TO public, test_schema;
test=> SELECT pg_catalog.pg_get_constraintdef(r.oid, true) FROM
test-> pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n
test-> ON n.oid = c.relnamespace
test-> JOIN pg_catalog.pg_constraint r  ON c.oid = r.conrelid
test-> WHERE c.relname='referring' AND r.contype = 'f'
test-> ;
               pg_get_constraintdef
---------------------------------------------------
 FOREIGN KEY (referred_id) REFERENCES referred(id)
(1 row)

Выше мы создали таблицу referred как член удаленной схемы test_schema, однако когда мы добавили test_schema к PG search_path и затем запросили pg_get_constraintdef() синтаксис FOREIGN KEY, test_schema не был включен в вывод функции.

С другой стороны, если мы вернем путь поиска к типичному значению по умолчанию public:

test=> SET search_path TO public;
SET

Тот же запрос к pg_get_constraintdef() теперь возвращает для нас полностью вычисленное по схеме имя:

test=> SELECT pg_catalog.pg_get_constraintdef(r.oid, true) FROM
test-> pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n
test-> ON n.oid = c.relnamespace
test-> JOIN pg_catalog.pg_constraint r  ON c.oid = r.conrelid
test-> WHERE c.relname='referring' AND r.contype = 'f';
                     pg_get_constraintdef
---------------------------------------------------------------
 FOREIGN KEY (referred_id) REFERENCES test_schema.referred(id)
(1 row)

SQLAlchemy по умолчанию будет использовать возвращаемое значение pg_get_constraintdef() для определения имени удаленной схемы. То есть, если наш search_path был установлен на включение test_schema, и мы вызвали процесс отражения таблицы следующим образом:

>>> from sqlalchemy import Table, MetaData, create_engine, text
>>> engine = create_engine("postgresql+psycopg2://scott:tiger@localhost/test")
>>> with engine.connect() as conn:
...     conn.execute(text("SET search_path TO test_schema, public"))
...     metadata_obj = MetaData()
...     referring = Table('referring', metadata_obj,
...                       autoload_with=conn)
...
<sqlalchemy.engine.result.CursorResult object at 0x101612ed0>

Вышеописанный процесс доставит в коллекцию MetaData.tables referred таблицу с именем без схемы:

>>> metadata_obj.tables['referred'].schema is None
True

Чтобы изменить поведение отражения таким образом, чтобы указанная схема сохранялась независимо от установки search_path, используйте опцию postgresql_ignore_search_path, которая может быть указана в качестве диалектного аргумента как для Table, так и для MetaData.reflect():

>>> with engine.connect() as conn:
...     conn.execute(text("SET search_path TO test_schema, public"))
...     metadata_obj = MetaData()
...     referring = Table('referring', metadata_obj,
...                       autoload_with=conn,
...                       postgresql_ignore_search_path=True)
...
<sqlalchemy.engine.result.CursorResult object at 0x1016126d0>

Теперь у нас будет test_schema.referred храниться как schema-qualified:

>>> metadata_obj.tables['test_schema.referred'].schema
'test_schema'

Обратите внимание, что ** во всех случаях** схема «по умолчанию» всегда отражается как None. Схема «по умолчанию» в PostgreSQL - это схема, возвращаемая функцией PostgreSQL current_schema(). В типичной установке PostgreSQL это имя public. Поэтому таблица, которая ссылается на другую, находящуюся в схеме public (т.е. по умолчанию), всегда будет иметь атрибут .schema, установленный в None.

См.также

Взаимодействие Schema-qualified Reflection со схемой по умолчанию - обсуждение вопроса с бэкенд-аг

The Schema Search Path - на сайте PostgreSQL.

ВСТАВКА/ОБНОВЛЕНИЕ… ВОЗВРАЩЕНИЕ

Диалект поддерживает синтаксисы PG 8.2 INSERT..RETURNING, UPDATE..RETURNING и DELETE..RETURNING. INSERT..RETURNING используется по умолчанию для однострочных операторов INSERT для получения вновь созданных идентификаторов первичного ключа. Чтобы указать явное предложение RETURNING, используйте метод _UpdateBase.returning() на основе каждого оператора:

# INSERT..RETURNING
result = table.insert().returning(table.c.col1, table.c.col2).\
    values(name='foo')
print(result.fetchall())

# UPDATE..RETURNING
result = table.update().returning(table.c.col1, table.c.col2).\
    where(table.c.name=='foo').values(name='bar')
print(result.fetchall())

# DELETE..RETURNING
result = table.delete().returning(table.c.col1, table.c.col2).\
    where(table.c.name=='foo')
print(result.fetchall())

INSERT…ON CONFLICT (Upsert)

Начиная с версии 9.5, PostgreSQL разрешает «апсерт» (обновление или вставку) строк в таблицу с помощью пункта ON CONFLICT оператора INSERT. Строка-кандидат будет вставлена только в том случае, если она не нарушает никаких уникальных ограничений. В случае нарушения уникальных ограничений может произойти вторичное действие, которое может быть либо «DO UPDATE», что указывает на то, что данные в целевой строке должны быть обновлены, либо «DO NOTHING», что означает молчаливый пропуск этой строки.

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

SQLAlchemy обеспечивает поддержку ON CONFLICT через специфическую для PostgreSQL функцию insert(), которая предоставляет генеративные методы Insert.on_conflict_do_update() и Insert.on_conflict_do_nothing():

>>> from sqlalchemy.dialects.postgresql import insert
>>> insert_stmt = insert(my_table).values(
...     id='some_existing_id',
...     data='inserted value')
>>> do_nothing_stmt = insert_stmt.on_conflict_do_nothing(
...     index_elements=['id']
... )
>>> print(do_nothing_stmt)
{printsql}INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s)
ON CONFLICT (id) DO NOTHING
{stop}

>>> do_update_stmt = insert_stmt.on_conflict_do_update(
...     constraint='pk_my_table',
...     set_=dict(data='updated value')
... )
>>> print(do_update_stmt)
{printsql}INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s)
ON CONFLICT ON CONSTRAINT pk_my_table DO UPDATE SET data = %(param_1)s

См.также

INSERT .. ON CONFLICT - в документации по PostgreSQL.

Указание цели

Оба метода определяют «цель» конфликта, используя либо именованное ограничение, либо умозаключение по столбцу:

  • Аргумент Insert.on_conflict_do_update.index_elements задает последовательность, содержащую строковые имена столбцов, объекты Column и/или элементы SQL выражения, которые будут идентифицировать уникальный индекс:

    >>> do_update_stmt = insert_stmt.on_conflict_do_update(
    ...     index_elements=['id'],
    ...     set_=dict(data='updated value')
    ... )
    >>> print(do_update_stmt)
    {printsql}INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s)
    ON CONFLICT (id) DO UPDATE SET data = %(param_1)s
    {stop}
    
    >>> do_update_stmt = insert_stmt.on_conflict_do_update(
    ...     index_elements=[my_table.c.id],
    ...     set_=dict(data='updated value')
    ... )
    >>> print(do_update_stmt)
    {printsql}INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s)
    ON CONFLICT (id) DO UPDATE SET data = %(param_1)s
  • При использовании Insert.on_conflict_do_update.index_elements для вывода индекса, частичный индекс можно вывести, указав также использование параметра Insert.on_conflict_do_update.index_where:

    >>> stmt = insert(my_table).values(user_email='a@b.com', data='inserted data')
    >>> stmt = stmt.on_conflict_do_update(
    ...     index_elements=[my_table.c.user_email],
    ...     index_where=my_table.c.user_email.like('%@gmail.com'),
    ...     set_=dict(data=stmt.excluded.data)
    ... )
    >>> print(stmt)
    {printsql}INSERT INTO my_table (data, user_email)
    VALUES (%(data)s, %(user_email)s) ON CONFLICT (user_email)
    WHERE user_email LIKE %(user_email_1)s DO UPDATE SET data = excluded.data
  • Аргумент Insert.on_conflict_do_update.constraint используется для прямого указания индекса, а не для его вывода. Это может быть имя ограничения UNIQUE, ограничения PRIMARY KEY или ИНДЕКСА:

    >>> do_update_stmt = insert_stmt.on_conflict_do_update(
    ...     constraint='my_table_idx_1',
    ...     set_=dict(data='updated value')
    ... )
    >>> print(do_update_stmt)
    {printsql}INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s)
    ON CONFLICT ON CONSTRAINT my_table_idx_1 DO UPDATE SET data = %(param_1)s
    {stop}
    
    >>> do_update_stmt = insert_stmt.on_conflict_do_update(
    ...     constraint='my_table_pk',
    ...     set_=dict(data='updated value')
    ... )
    >>> print(do_update_stmt)
    {printsql}INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s)
    ON CONFLICT ON CONSTRAINT my_table_pk DO UPDATE SET data = %(param_1)s
    {stop}
  • Аргумент Insert.on_conflict_do_update.constraint может также ссылаться на конструкцию SQLAlchemy, представляющую ограничение, например, UniqueConstraint, PrimaryKeyConstraint, Index или ExcludeConstraint. При таком использовании, если ограничение имеет имя, оно используется напрямую. В противном случае, если ограничение не имеет имени, то будет использовано умозаключение, где выражения и необязательное предложение WHERE ограничения будут прописаны в конструкции. Это использование особенно удобно для ссылки на именованный или неименованный первичный ключ Table с помощью атрибута Table.primary_key:

    >>> do_update_stmt = insert_stmt.on_conflict_do_update(
    ...     constraint=my_table.primary_key,
    ...     set_=dict(data='updated value')
    ... )
    >>> print(do_update_stmt)
    {printsql}INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s)
    ON CONFLICT (id) DO UPDATE SET data = %(param_1)s

Оговорка SET

ON CONFLICT...DO UPDATE используется для выполнения обновления уже существующего ряда, используя любую комбинацию новых значений, а также значений из предлагаемой вставки. Эти значения задаются с помощью параметра Insert.on_conflict_do_update.set_. Этот параметр принимает словарь, состоящий из прямых значений для UPDATE:

>>> stmt = insert(my_table).values(id='some_id', data='inserted value')
>>> do_update_stmt = stmt.on_conflict_do_update(
...     index_elements=['id'],
...     set_=dict(data='updated value')
... )
>>> print(do_update_stmt)
{printsql}INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s)
ON CONFLICT (id) DO UPDATE SET data = %(param_1)s

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

Метод Insert.on_conflict_do_update() не принимает во внимание значения UPDATE по умолчанию на стороне Python или функции генерации, например, указанные с помощью Column.onupdate. Эти значения не будут использоваться для UPDATE в стиле ON CONFLICT, если они не указаны вручную в словаре Insert.on_conflict_do_update.set_.

Обновление с использованием исключенных значений INSERT

Для того чтобы ссылаться на предлагаемую строку вставки, специальный псевдоним Insert.excluded доступен в качестве атрибута на объекте Insert; этот объект является ColumnCollection, псевдоним которого содержит все столбцы целевой таблицы:

>>> stmt = insert(my_table).values(
...     id='some_id',
...     data='inserted value',
...     author='jlh'
... )
>>> do_update_stmt = stmt.on_conflict_do_update(
...     index_elements=['id'],
...     set_=dict(data='updated value', author=stmt.excluded.author)
... )
>>> print(do_update_stmt)
{printsql}INSERT INTO my_table (id, data, author)
VALUES (%(id)s, %(data)s, %(author)s)
ON CONFLICT (id) DO UPDATE SET data = %(param_1)s, author = excluded.author

Дополнительные критерии ГДЕ

Метод Insert.on_conflict_do_update() также принимает предложение WHERE с помощью параметра Insert.on_conflict_do_update.where, который ограничивает строки, получающие UPDATE:

>>> stmt = insert(my_table).values(
...     id='some_id',
...     data='inserted value',
...     author='jlh'
... )
>>> on_update_stmt = stmt.on_conflict_do_update(
...     index_elements=['id'],
...     set_=dict(data='updated value', author=stmt.excluded.author),
...     where=(my_table.c.status == 2)
... )
>>> print(on_update_stmt)
{printsql}INSERT INTO my_table (id, data, author)
VALUES (%(id)s, %(data)s, %(author)s)
ON CONFLICT (id) DO UPDATE SET data = %(param_1)s, author = excluded.author
WHERE my_table.status = %(status_1)s

Скакалка с «НЕЛЬЗЯ

ON CONFLICT можно использовать для полного пропуска вставки строки, если возникает конфликт с уникальным или исключающим ограничением; ниже это показано на примере метода Insert.on_conflict_do_nothing():

>>> stmt = insert(my_table).values(id='some_id', data='inserted value')
>>> stmt = stmt.on_conflict_do_nothing(index_elements=['id'])
>>> print(stmt)
{printsql}INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s)
ON CONFLICT (id) DO NOTHING

Если DO NOTHING используется без указания столбцов или ограничений, это приводит к пропуску INSERT для любого нарушения уникального или исключающего ограничения, которое имеет место:

>>> stmt = insert(my_table).values(id='some_id', data='inserted value')
>>> stmt = stmt.on_conflict_do_nothing()
>>> print(stmt)
{printsql}INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s)
ON CONFLICT DO NOTHING

ТОЛЬКО …

Диалект поддерживает ключевое слово ONLY в PostgreSQL для указания только определенной таблицы в иерархии наследования. Это может использоваться для создания синтаксисов SELECT ... FROM ONLY, UPDATE ONLY ... и DELETE FROM ONLY .... Он использует механизм подсказок SQLAlchemy:

# SELECT ... FROM ONLY ...
result = table.select().with_hint(table, 'ONLY', 'postgresql')
print(result.fetchall())

# UPDATE ONLY ...
table.update(values=dict(foo='bar')).with_hint('ONLY',
                                               dialect_name='postgresql')

# DELETE FROM ONLY ...
table.delete().with_hint('ONLY', dialect_name='postgresql')

Параметры индекса, специфичные для PostgreSQL

Существует несколько расширений конструкции Index, специфичных для диалекта PostgreSQL.

Охватывающие индексы

Опция postgresql_include выводит INCLUDE(colname) для заданных строковых имен:

Index("my_index", table.c.x, postgresql_include=['y'])

будет отображать индекс как CREATE INDEX my_index ON table (x) INCLUDE (y).

Обратите внимание, что эта функция требует PostgreSQL 11 или более поздней версии.

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

Частичные индексы

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

Index('my_index', my_table.c.id, postgresql_where=my_table.c.value > 10)

Классы операторов

PostgreSQL позволяет указать класс оператора для каждого столбца индекса (см. https://www.postgresql.org/docs/current/interactive/indexes-opclass.html). Конструкция Index позволяет указать их с помощью аргумента postgresql_ops ключевого слова:

Index(
    'my_index', my_table.c.id, my_table.c.data,
    postgresql_ops={
        'data': 'text_pattern_ops',
        'id': 'int4_ops'
    })

Обратите внимание, что ключи в словарях postgresql_ops являются именем «ключа» Column, т.е. именем, используемым для доступа к нему из коллекции .c Table, которое может быть настроено так, чтобы отличаться от фактического имени столбца, выраженного в базе данных.

Если postgresql_ops используется против сложного выражения SQL, такого как вызов функции, то для применения к столбцу ему должна быть присвоена метка, которая идентифицируется в словаре по имени, например:

Index(
    'my_index', my_table.c.id,
    func.lower(my_table.c.data).label('data_lower'),
    postgresql_ops={
        'data_lower': 'text_pattern_ops',
        'id': 'int4_ops'
    })

Классы операторов также поддерживаются конструкцией ExcludeConstraint с помощью параметра ExcludeConstraint.ops. Подробности см. в этом параметре.

Добавлено в версии 1.3.21: добавлена поддержка классов операторов с ExcludeConstraint.

Типы индексов

PostgreSQL предоставляет несколько типов индексов: B-Tree, Hash, GiST и GIN, а также возможность для пользователей создавать свои собственные (см. https://www.postgresql.org/docs/current/static/indexes-types.html). Их можно указать в Index с помощью аргумента postgresql_using ключевого слова:

Index('my_index', my_table.c.data, postgresql_using='gin')

Значение, переданное в аргументе keyword, будет просто передано команде CREATE INDEX, поэтому оно должно быть действительным типом индекса для вашей версии PostgreSQL.

Параметры хранения индексов

PostgreSQL позволяет задавать параметры хранения для индексов. Доступные параметры хранения зависят от метода индекса, используемого индексом. Параметры хранения могут быть заданы на Index с помощью аргумента postgresql_with с ключевым словом:

Index('my_index', my_table.c.data, postgresql_with={"fillfactor": 50})

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

Index('my_index', my_table.c.data, postgresql_tablespace='my_tablespace')

Обратите внимание, что эта же опция доступна и для Table.

Индексы с CONCURRENTLY

Опция индекса PostgreSQL CONCURRENTLY поддерживается путем передачи флага postgresql_concurrently в конструкцию Index:

tbl = Table('testtbl', m, Column('data', Integer))

idx1 = Index('test_idx1', tbl.c.data, postgresql_concurrently=True)

Приведенная выше конструкция индекса приведет DDL для CREATE INDEX, при условии, что обнаружен PostgreSQL 8.2 или выше, или для диалекта без подключения, как:

CREATE INDEX CONCURRENTLY test_idx1 ON testtbl (data)

Для DROP INDEX, если обнаружен PostgreSQL 9.2 или выше, или для диалекта без соединения, будет выдано:

DROP INDEX CONCURRENTLY test_idx1

При использовании CONCURRENTLY база данных PostgreSQL требует, чтобы оператор был вызван вне блока транзакций. Python DBAPI требует, чтобы даже для одного оператора транзакция присутствовала, поэтому для использования этой конструкции необходимо использовать режим «autocommit» DBAPI:

metadata = MetaData()
table = Table(
    "foo", metadata,
    Column("id", String))
index = Index(
    "foo_idx", table.c.id, postgresql_concurrently=True)

with engine.connect() as conn:
    with conn.execution_options(isolation_level='AUTOCOMMIT'):
        table.create(conn)

Отражение индекса PostgreSQL

База данных PostgreSQL неявно создает UNIQUE INDEX при использовании конструкции UNIQUE CONSTRAINT. При проверке таблицы с помощью Inspector, Inspector.get_indexes() и Inspector.get_unique_constraints() будут сообщать об этих двух конструкциях отдельно; в случае индекса ключ duplicates_constraint будет присутствовать в записи индекса, если будет обнаружено, что он зеркально отражает ограничение. При выполнении отражения с помощью Table(..., autoload_with=engine), UNIQUE INDEX не возвращается в Table.indexes, если обнаруживается, что он зеркально отражает UniqueConstraint в коллекции Table.constraints.

Специальные опции отражения

Inspector, используемый для бэкенда PostgreSQL, является экземпляром PGInspector, который предлагает дополнительные методы:

from sqlalchemy import create_engine, inspect

engine = create_engine("postgresql+psycopg2://localhost/test")
insp = inspect(engine)  # will be a PGInspector

print(insp.get_enums())
Object Name Description

PGInspector

class sqlalchemy.dialects.postgresql.base.PGInspector
method sqlalchemy.dialects.postgresql.base.PGInspector.get_domains(schema: Optional[str] = None) List[ReflectedDomain]

Возвращает список объектов DOMAIN.

Каждый член представляет собой словарь, содержащий эти поля:

  • имя - имя домена

  • schema - имя схемы для домена.

  • visible - булево значение, является ли данный домен видимым в пути поиска по умолчанию.

  • type - тип, определенный данным доменом.

  • nullable - Указывает, может ли этот домен быть NULL.

  • default - Значение по умолчанию для домена или None, если домен не имеет значения по умолчанию.

  • constraints - Список dict, содержащий ограничения, определенные данным доменом. Каждый элемент содержит два ключа: name из ограничения и check с текстом ограничения.

Параметры:

schema – имя схемы. Если None, используется схема по умолчанию (обычно „public“). Может также иметь значение '*' для указания доменов нагрузки для всех схем.

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

method sqlalchemy.dialects.postgresql.base.PGInspector.get_enums(schema: Optional[str] = None) List[ReflectedEnum]

Возвращает список объектов ENUM.

Каждый член представляет собой словарь, содержащий эти поля:

  • имя - имя перечисления

  • schema - имя схемы для перечисления.

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

  • labels - список строковых меток, которые применяются к перечислению.

Параметры:

schema – имя схемы. Если None, используется схема по умолчанию (обычно „public“). Может также иметь значение '*' для указания загрузки перечислений для всех схем.

method sqlalchemy.dialects.postgresql.base.PGInspector.get_foreign_table_names(schema: Optional[str] = None) List[str]

Возвращает список FOREIG

Поведение аналогично поведению Inspector.get_table_names(), за исключением того, что список ограничен теми таблицами, которые сообщают relkind значение f.

method sqlalchemy.dialects.postgresql.base.PGInspector.get_table_oid(table_name: str, schema: Optional[str] = None) int

Возвращает OID для заданного имени таблицы.

Параметры:
  • table_name – строковое имя таблицы. Для специального цитирования используйте quoted_name.

  • schema – string имя схемы; если опущено, используется схема по умолчанию соединения с базой данных. Для специального цитирования используйте quoted_name.

method sqlalchemy.dialects.postgresql.base.PGInspector.has_type(type_name: str, schema: Optional[str] = None, **kw: Any) bool

Возвращает, имеет ли база данных указанный тип в предоставленной схеме.

Параметры:
  • type_name – тип для проверки.

  • schema – имя схемы. Если None, используется схема по умолчанию (обычно „public“). Может также иметь значение '*' для проверки всех схем.

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

Параметры таблиц PostgreSQL

Несколько опций для CREATE TABLE поддерживаются непосредственно диалектом PostgreSQL в сочетании с конструкцией Table:

  • TABLESPACE:

    Table("some_table", metadata, ..., postgresql_tablespace='some_tablespace')

    Приведенная выше опция также доступна для конструкции Index.

  • ON COMMIT:

    Table("some_table", metadata, ..., postgresql_on_commit='PRESERVE ROWS')
  • WITH OIDS:

    Table("some_table", metadata, ..., postgresql_with_oids=True)
  • WITHOUT OIDS:

    Table("some_table", metadata, ..., postgresql_with_oids=False)
  • INHERITS:

    Table("some_table", metadata, ..., postgresql_inherits="some_supertable")
    
    Table("some_table", metadata, ..., postgresql_inherits=("t1", "t2", ...))
  • PARTITION BY:

    Table("some_table", metadata, ...,
          postgresql_partition_by='LIST (part_column)')
    
    .. versionadded:: 1.2.6

См.также

PostgreSQL CREATE TABLE options - в документации по PostgreSQL.

Параметры ограничений PostgreSQL

Следующие опции поддерживаются диалектом PostgreSQL в сочетании с выбранными конструкциями ограничений:

  • NOT VALID: Эта опция применяется к CHECK и FOREIG

    При использовании инструмента миграции SQL, такого как Alembic, который отображает конструкции ALTER TABLE, аргумент postgresql_not_valid может быть указан как дополнительный аргумент ключевого слова в операции, которая создает ограничение, как в следующем примере Alembic:

    def update():
        op.create_foreign_key(
            "fk_user_address",
            "address",
            "user",
            ["user_id"],
            ["id"],
            postgresql_not_valid=True
        )

    В конечном итоге ключевое слово принимается непосредственно конструкциями CheckConstraint, ForeignKeyConstraint и ForeignKey; при использовании такого инструмента, как Alembic, специфические для диалекта аргументы ключевого слова передаются этим конструкциям из директив операций миграции:

    CheckConstraint("some_field IS NOT NULL", postgresql_not_valid=True)
    
    ForeignKeyConstraint(["some_id"], ["some_table.some_id"], postgresql_not_valid=True)

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

    См.также

    PostgreSQL ALTER TABLE options - в документации по PostgreSQL.

Табличные значения, функции, оценивающие таблицы и столбцы, объекты Row и Tuple

В PostgreSQL широко используются современные формы SQL, такие как функции с табличным значением, таблицы и строки как значения. Эти конструкции широко используются как часть поддержки PostgreSQL сложных типов данных, таких как JSON, ARRAY и другие типы данных. Язык SQL-выражений SQLAlchemy имеет встроенную поддержку большинства таблично-значимых и строчно-значимых форм.

Функции с табличными значениями

Многие встроенные функции PostgreSQL предназначены для использования в предложении FROM оператора SELECT и способны возвращать строки таблицы или наборы строк таблицы. Большая часть функций PostgreSQL JSON, например, такие как json_array_elements(), json_object_keys(), json_each_text(), json_each(), json_to_record(), json_populate_recordset() используют такие формы. Эти классы форм вызова SQL-функций в SQLAlchemy доступны с помощью метода FunctionElement.table_valued() в сочетании с объектами Function, сгенерированными из пространства имен func.

Ниже приведены примеры из справочной документации PostgreSQL:

  • json_each():

    >>> from sqlalchemy import select, func
    >>> stmt = select(func.json_each('{"a":"foo", "b":"bar"}').table_valued("key", "value"))
    >>> print(stmt)
    {printsql}SELECT anon_1.key, anon_1.value
    FROM json_each(:json_each_1) AS anon_1
  • json_populate_record():

    >>> from sqlalchemy import select, func, literal_column
    >>> stmt = select(
    ...     func.json_populate_record(
    ...         literal_column("null::myrowtype"),
    ...         '{"a":1,"b":2}'
    ...     ).table_valued("a", "b", name="x")
    ... )
    >>> print(stmt)
    {printsql}SELECT x.a, x.b
    FROM json_populate_record(null::myrowtype, :json_populate_record_1) AS x
  • json_to_record() - эта форма использует специфическую для PostgreSQL форму производных колонок в псевдониме, где мы можем использовать элементы column() с типами для их создания. Метод FunctionElement.table_valued() производит конструкцию TableValuedAlias, а метод TableValuedAlias.render_derived() задает спецификацию производных колонок:

    >>> from sqlalchemy import select, func, column, Integer, Text
    >>> stmt = select(
    ...     func.json_to_record('{"a":1,"b":[1,2,3],"c":"bar"}').table_valued(
    ...         column("a", Integer), column("b", Text), column("d", Text),
    ...     ).render_derived(name="x", with_types=True)
    ... )
    >>> print(stmt)
    {printsql}SELECT x.a, x.b, x.d
    FROM json_to_record(:json_to_record_1) AS x(a INTEGER, b TEXT, d TEXT)
  • WITH ORDINALITY - часть стандарта SQL, WITH ORDINALITY добавляет порядковый счетчик к выходу функции и принимается ограниченным набором функций PostgreSQL, включая unnest() и generate_series(). Метод FunctionElement.table_valued() принимает для этой цели параметр ключевого слова with_ordinality, который принимает строковое имя, которое будет применено к столбцу «порядковый номер»:

    >>> from sqlalchemy import select, func
    >>> stmt = select(
    ...     func.generate_series(4, 1, -1).
    ...     table_valued("value", with_ordinality="ordinality").
    ...     render_derived()
    ... )
    >>> print(stmt)
    {printsql}SELECT anon_1.value, anon_1.ordinality
    FROM generate_series(:generate_series_1, :generate_series_2, :generate_series_3)
    WITH ORDINALITY AS anon_1(value, ordinality)

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

Функции, оцениваемые по столбцам

Подобно функции, оцениваемой по таблице, функция, оцениваемая по столбцу, присутствует в предложении FROM, но передает себя в предложении columns как одно скалярное значение. PostgreSQL функции, такие как json_array_elements(), unnest() и generate_series() могут использовать эту форму. Функции, оцениваемые по столбцам, доступны с помощью метода FunctionElement.column_valued() в FunctionElement:

  • json_array_elements():

    >>> from sqlalchemy import select, func
    >>> stmt = select(func.json_array_elements('["one", "two"]').column_valued("x"))
    >>> print(stmt)
    {printsql}SELECT x
    FROM json_array_elements(:json_array_elements_1) AS x
  • unnest() - для генерации литерала PostgreSQL ARRAY может быть использована конструкция array():

    >>> from sqlalchemy.dialects.postgresql import array
    >>> from sqlalchemy import select, func
    >>> stmt = select(func.unnest(array([1, 2])).column_valued())
    >>> print(stmt)
    {printsql}SELECT anon_1
    FROM unnest(ARRAY[%(param_1)s, %(param_2)s]) AS anon_1

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

    >>> from sqlalchemy import table, column, ARRAY, Integer
    >>> from sqlalchemy import select, func
    >>> t = table("t", column('value', ARRAY(Integer)))
    >>> stmt = select(func.unnest(t.c.value).column_valued("unnested_value"))
    >>> print(stmt)
    {printsql}SELECT unnested_value
    FROM unnest(t.value) AS unnested_value

Типы строк

Встроенная поддержка для отображения ROW может быть приближена с помощью func.ROW с пространством имен sqlalchemy.func или с помощью конструкции tuple_():

>>> from sqlalchemy import table, column, func, tuple_
>>> t = table("t", column("id"), column("fk"))
>>> stmt = t.select().where(
...     tuple_(t.c.id, t.c.fk) > (1,2)
... ).where(
...     func.ROW(t.c.id, t.c.fk) < func.ROW(3, 7)
... )
>>> print(stmt)
{printsql}SELECT t.id, t.fk
FROM t
WHERE (t.id, t.fk) > (:param_1, :param_2) AND ROW(t.id, t.fk) < ROW(:ROW_1, :ROW_2)

Типы таблиц, передаваемые функциям

PostgreSQL поддерживает передачу таблицы в качестве аргумента функции, которую он называет типом «запись». Объекты SQLAlchemy FromClause, такие как Table, поддерживают эту специальную форму с помощью метода FromClause.table_valued(), который сравним с методом FunctionElement.table_valued(), за исключением того, что коллекция столбцов уже установлена самим FromClause:

>>> from sqlalchemy import table, column, func, select
>>> a = table( "a", column("id"), column("x"), column("y"))
>>> stmt = select(func.row_to_json(a.table_valued()))
>>> print(stmt)
{printsql}SELECT row_to_json(a) AS row_to_json_1
FROM a

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

Типы ARRAY

Диалект PostgreSQL поддерживает массивы, как в виде многомерных типов столбцов, так и в виде литералов массивов:

  • ARRAY - тип данных ARRAY

  • array - литерал массива

  • array_agg() - SQL-функция ARRAY_AGG

  • aggregate_order_by - помощник для синтаксиса агрегатной функции ORDER BY в PG.

Типы JSON

Диалект PostgreSQL поддерживает оба типа данных JSON и JSONB, включая встроенную поддержку psycopg2 и поддержку всех специальных операторов PostgreSQL:

Тип HSTORE

Поддерживается тип PostgreSQL HSTORE, а также литералы hstore:

  • HSTORE - тип данных HSTORE

  • hstore - литерал hstore

Типы ENUM

В PostgreSQL есть независимо создаваемая структура TYPE, которая используется для реализации перечислимого типа. Этот подход вводит сиг

Использование ENUM с ARRAY

Комбинация ENUM и ARRAY в настоящее время напрямую не поддерживается внутренними DBAPI. До версии SQLAlchemy 1.3.17 для того, чтобы эта комбинация работала, требовалось специальное обходное решение, описанное ниже.

Изменено в версии 1.3.17: Комбинация ENUM и ARRAY теперь напрямую обрабатывается реализацией SQLAlchemy без каких-либо обходных путей.

from sqlalchemy import TypeDecorator
from sqlalchemy.dialects.postgresql import ARRAY


class ArrayOfEnum(TypeDecorator):
    impl = ARRAY

    def bind_expression(self, bindvalue):
        return sa.cast(bindvalue, self)

    def result_processor(self, dialect, coltype):
        super_rp = super(ArrayOfEnum, self).result_processor(dialect, coltype)

        def handle_raw_string(value):
            inner = re.match(r"^{(.*)}$", value).group(1)
            return inner.split(",") if inner else []

        def process(value):
            if value is None:
                return None
            return super_rp(handle_raw_string(value))

        return process

Например:

Table(
    "mydata",
    metadata,
    Column("id", Integer, primary_key=True),
    Column("data", ArrayOfEnum(ENUM("a", "b", "c", name="myenum"))),
)

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

Использование JSON/JSONB с ARRAY

Аналогично использованию ENUM, до версии SQLAlchemy 1.3.17, для ARRAY из JSON/JSONB нам необходимо создать соответствующий CAST. Текущие драйверы psycopg2 корректно отображают набор результатов без каких-либо специальных действий.

Изменено в версии 1.3.17: Комбинация JSON/JSONB и ARRAY теперь напрямую обрабатывается реализацией SQLAlchemy без каких-либо обходных путей.

class CastingArray(ARRAY):
    def bind_expression(self, bindvalue):
        return sa.cast(bindvalue, self)

Например:

Table(
    "mydata",
    metadata,
    Column("id", Integer, primary_key=True),
    Column("data", CastingArray(JSONB)),
)

Типы диапазонов и мультидиапазонов

Диапазон и многодиапазонные типы PostgreSQL поддерживаются для диалектов psycopg2, psycopg и asyncpg.

Значения данных, передаваемые в базу данных, могут быть переданы как строковые значения или с помощью объекта данных Range.

Добавлено в версии 2.0: Добавлен бэкенд-аг

Например, пример полностью типизированной модели, использующей тип данных TSRANGE:

from datetime import datetime

from sqlalchemy.dialects.postgresql import Range
from sqlalchemy.dialects.postgresql import TSRANGE
from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column


class Base(DeclarativeBase):
    pass


class RoomBooking(Base):
    __tablename__ = "room_booking"

    id: Mapped[int] = mapped_column(primary_key=True)
    room: Mapped[str]
    during: Mapped[Range[datetime]] = mapped_column(TSRANGE)

Для представления данных для столбца during выше, тип Range - это простой класс данных, который будет представлять границы диапазона. Ниже показан INSERT строки в вышеприведенную таблицу room_booking:

from sqlalchemy import create_engine
from sqlalchemy.orm import Session

engine = create_engine("postgresql+psycopg://scott:tiger@pg14/dbname")

Base.metadata.create_all(engine)

with Session(engine) as session:
    booking = RoomBooking(
        room="101", during=Range(datetime(2013, 3, 23), datetime(2013, 3, 25))
    )
    session.add(booking)
    session.commit()

Выбор из любого столбца диапазона также возвращает Range объектов, как указано:

from sqlalchemy import select

with Session(engine) as session:
    for row in session.execute(select(RoomBooking.during)):
        print(row)

Ниже перечислены доступные типы данных диапазона:

Object Name Description

Range

Представляет собой диапазон PostgreSQL.

class sqlalchemy.dialects.postgresql.Range

Представляет собой диапазон PostgreSQL.

Например:

r = Range(10, 50, bounds="()")

Стиль вызова похож на стиль вызова psycopg и psycopg2, отчасти для того, чтобы облегчить миграцию с предыдущих версий SQLAlchemy, которые использовали эти объекты напрямую.

Параметры:
  • lower – Значение нижней границы, или Нет

  • upper – Верхнее граничное значение, или Нет

  • bounds – только ключевое слово, необязательное строковое значение, которое является одним из "()", "[)", "(]", "[]". По умолчанию это значение равно "[)".

  • empty – только ключевое слово, необязательный bool, указывающий, что это «пустой» диапазон

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

**Классный сиг

класс sqlalchemy.dialects.postgresql.Range (typing.Generic)

method sqlalchemy.dialects.postgresql.Range.__eq__(other: Any) bool

Сравните этот диапазон с другим с учетом инклюзивности границ, возвращая True, если они равны.

method sqlalchemy.dialects.postgresql.Range.adjacent_to(other: Range[_T]) bool

Определите, является ли этот диапазон смежным с другим.

method sqlalchemy.dialects.postgresql.Range.contained_by(other: Range[_T]) bool

Определите, является ли этот диапазон содержащимся в other.

method sqlalchemy.dialects.postgresql.Range.contains(value: Union[_T, Range[_T]]) bool

Определите, содержит ли данный диапазон значение.

method sqlalchemy.dialects.postgresql.Range.difference(other: Range[_T]) Range[_T]

Вычислите разницу между этим диапазоном и другим.

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

method sqlalchemy.dialects.postgresql.Range.intersection(other: Range[_T]) Range[_T]

Вычислите пересечение этого диапазона с другим.

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

attribute sqlalchemy.dialects.postgresql.Range.is_empty

Синоним атрибута „empty“.

attribute sqlalchemy.dialects.postgresql.Range.isempty

Синоним атрибута „empty“.

attribute sqlalchemy.dialects.postgresql.Range.lower: Optional[_T]

нижняя граница

attribute sqlalchemy.dialects.postgresql.Range.lower_inc

Возвращает True, если нижняя граница является инклюзивной.

attribute sqlalchemy.dialects.postgresql.Range.lower_inf

Возвращает True, если этот диапазон непуст и нижняя граница бесконечна.

method sqlalchemy.dialects.postgresql.Range.not_extend_left_of(other: Range[_T]) bool

Определите, не распространяется ли это слева от other.

method sqlalchemy.dialects.postgresql.Range.not_extend_right_of(other: Range[_T]) bool

Определите, не распространяется ли это на право другой.

method sqlalchemy.dialects.postgresql.Range.overlaps(other: Range[_T]) bool

Определите, пересекается ли этот диапазон с другим.

method sqlalchemy.dialects.postgresql.Range.strictly_left_of(other: Range[_T]) bool

Определите, находится ли этот диапазон полностью слева от other.

method sqlalchemy.dialects.postgresql.Range.strictly_right_of(other: Range[_T]) bool

Определите, находится ли этот диапазон полностью справа от other.

method sqlalchemy.dialects.postgresql.Range.union(other: Range[_T]) Range[_T]

Вычислите объединение этого диапазона с другим.

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

attribute sqlalchemy.dialects.postgresql.Range.upper: Optional[_T]

верхняя граница

attribute sqlalchemy.dialects.postgresql.Range.upper_inc

Возвращает True, если верхняя граница является инклюзивной.

attribute sqlalchemy.dialects.postgresql.Range.upper_inf

Возвращает True, если этот диапазон непустой и верхняя граница бесконечна.

Мультидиапазоны

Мультидиапазоны поддерживаются PostgreSQL 14 и выше. Мультидиапазонные типы данных SQLAlchemy работают со списками типов Range.

Добавлено в версии 2.0: Добавлена поддержка типов данных MULTIRANGE. В отличие от функции psycopg мультидиапазона, адаптация SQLAlchemy представляет мультидиапазонный тип данных как список объектов Range.

Пример ниже иллюстрирует использование типа данных TSMULTIRANGE:

from datetime import datetime
from typing import List

from sqlalchemy.dialects.postgresql import Range
from sqlalchemy.dialects.postgresql import TSMULTIRANGE
from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column


class Base(DeclarativeBase):
    pass


class EventCalendar(Base):
    __tablename__ = "event_calendar"

    id: Mapped[int] = mapped_column(primary_key=True)
    event_name: Mapped[str]
    in_session_periods: Mapped[List[Range[datetime]]] = mapped_column(TSMULTIRANGE)

Иллюстрация вставки и выбора записи:

from sqlalchemy import create_engine
from sqlalchemy import select
from sqlalchemy.orm import Session

engine = create_engine("postgresql+psycopg://scott:tiger@pg14/test")

Base.metadata.create_all(engine)

with Session(engine) as session:
    calendar = EventCalendar(
        event_name="SQLAlchemy Tutorial Sessions",
        in_session_periods=[
            Range(datetime(2013, 3, 23), datetime(2013, 3, 25)),
            Range(datetime(2013, 4, 12), datetime(2013, 4, 15)),
            Range(datetime(2013, 5, 9), datetime(2013, 5, 12)),
        ],
    )
    session.add(calendar)
    session.commit()

    for multirange in session.scalars(select(EventCalendar.in_session_periods)):
        for range_ in multirange:
            print(f"Start: {range_.lower}  End: {range_.upper}")

Примечание

В приведенном выше примере список типов Range, обрабатываемый ORM, не будет автоматически определять изменения на месте для конкретного значения списка; чтобы обновить значения списка с помощью ORM, либо переназначьте их.

Ниже перечислены доступные многодиапазонные типы данных:

Типы данных PostgreSQL

Как и во всех диалектах SQLAlchemy, все типы UPPERCASE, которые, как известно, действительны в PostgreSQL, импортируются из диалекта верхнего уровня, независимо от того, происходят ли они из sqlalchemy.types или из локального диалекта:

from sqlalchemy.dialects.postgresql import (
    ARRAY,
    BIGINT,
    BIT,
    BOOLEAN,
    BYTEA,
    CHAR,
    CIDR,
    CITEXT,
    DATE,
    DOUBLE_PRECISION,
    ENUM,
    FLOAT,
    HSTORE,
    INET,
    INTEGER,
    INTERVAL,
    JSON,
    JSONB,
    MACADDR,
    MACADDR8,
    MONEY,
    NUMERIC,
    OID,
    REAL,
    SMALLINT,
    TEXT,
    TIME,
    TIMESTAMP,
    UUID,
    VARCHAR,
    INT4RANGE,
    INT8RANGE,
    NUMRANGE,
    DATERANGE,
    TSRANGE,
    TSTZRANGE,
    REGCONFIG,
    REGCLASS,
    TSQUERY,
    TSVECTOR,
)

Ниже перечислены типы, специфичные для PostgreSQL или имеющие специфичные для PostgreSQL аргументы построения:

Object Name Description

AbstractMultiRange

база для типов PostgreSQL MULTIRANGE

AbstractRange

База для типов RANGE в PostgreSQL.

ARRAY

Тип PostgreSQL ARRAY.

BIT

BYTEA

CIDR

CITEXT

Укажите тип PostgreSQL CITEXT.

DATEMULTIRANGE

Представляет тип PostgreSQL DATEMULTIRANGE.

DATERANGE

Представляет тип PostgreSQL DATERANGE.

DOMAIN

Представляет тип DOMAIN PostgreSQL.

ENUM

Тип PostgreSQL ENUM.

HSTORE

Представляет собой тип PostgreSQL HSTORE.

INET

INT4MULTIRANGE

Представляет тип PostgreSQL INT4MULTIRANGE.

INT4RANGE

Представляет тип PostgreSQL INT4RANGE.

INT8MULTIRANGE

Представляет тип PostgreSQL INT8MULTIRANGE.

INT8RANGE

Представляет тип PostgreSQL INT8RANGE.

INTERVAL

PostgreSQL Тип INTERVAL.

JSON

Представляет тип PostgreSQL JSON.

JSONB

Представляет тип PostgreSQL JSONB.

JSONPATH

JSON Тип пути.

MACADDR

MACADDR8

MONEY

Укажите тип PostgreSQL MONEY.

NUMMULTIRANGE

Представляет тип PostgreSQL NUMMULTIRANGE.

NUMRANGE

Представляет тип PostgreSQL NUMRANGE.

OID

Укажите тип OID PostgreSQL.

REGCLASS

Укажите тип PostgreSQL REGCLASS.

REGCONFIG

Укажите тип PostgreSQL REGCONFIG.

TIME

PostgreSQL Тип времени.

TIMESTAMP

Укажите тип PostgreSQL TIMESTAMP.

TSMULTIRANGE

Представляет тип PostgreSQL TSRANGE.

TSQUERY

Укажите тип PostgreSQL TSQUERY.

TSRANGE

Представляет тип PostgreSQL TSRANGE.

TSTZMULTIRANGE

Представляет тип PostgreSQL TSTZRANGE.

TSTZRANGE

Представляет тип PostgreSQL TSTZRANGE.

TSVECTOR

Тип TSVECTOR реализует тип текстового поиска PostgreSQL TSVECTOR.

class sqlalchemy.dialects.postgresql.AbstractRange

База для типов RANGE в PostgreSQL.

См.также

PostgreSQL range functions

class comparator_factory

Определите операции сравнения для типов диапазонов.

**Классный сиг

класс sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory (sqlalchemy.types.Comparator)

method sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.adjacent_to(other: Any) ColumnElement[bool]

Булево выражение. Возвращает true, если диапазон в столбце является смежным с диапазоном в операнде.

method sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.contained_by(other: Any) ColumnElement[bool]

Булево выражение. Возвращает true, если столбец содержится в правом операнде.

method sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.contains(other: Any, **kw: Any) ColumnElement[bool]

Булево выражение. Возвращает true, если правый операнд, который может быть элементом или диапазоном, содержится в столбце.

kwargs может быть ig

method sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.difference(other: Any) ColumnElement[bool]

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

method sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.intersection(other: Any) ColumnElement[Range[_T]]

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

method sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.not_extend_left_of(other: Any) ColumnElement[bool]

Булево выражение. Возвращает true, если диапазон в столбце не простирается влево от диапазона в операнде.

method sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.not_extend_right_of(other: Any) ColumnElement[bool]

Булево выражение. Возвращает true, если диапазон в столбце не простирается вправо от диапазона в операнде.

method sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.overlaps(other: Any) ColumnElement[bool]

Булево выражение. Возвращает true, если колонка перекрывает (имеет общие точки с) правый операнд.

method sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.strictly_left_of(other: Any) ColumnElement[bool]

Булево выражение. Возвращает true, если столбец находится строго слева от правого операнда.

method sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.strictly_right_of(other: Any) ColumnElement[bool]

Булево выражение. Возвращает true, если столбец находится строго справа от правого операнда.

method sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.union(other: Any) ColumnElement[bool]

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

class sqlalchemy.dialects.postgresql.AbstractMultiRange

база для типов PostgreSQL MULTIRANGE

class sqlalchemy.dialects.postgresql.ARRAY

Тип PostgreSQL ARRAY.

Тип ARRAY строится так же, как и основной тип ARRAY; требуется тип-член, и рекомендуется указать число измерений, если тип будет использоваться для более чем одного измерения:

from sqlalchemy.dialects import postgresql

mytable = Table("mytable", metadata,
        Column("data", postgresql.ARRAY(Integer, dimensions=2))
    )

Тип ARRAY предоставляет все операции, определенные для основного типа ARRAY, включая поддержку «размеров», индексированный доступ и простое сопоставление, такое как Comparator.any() и Comparator.all(). Класс ARRAY также предоставляет специфические для PostgreSQL методы для операций сдерживания, включая Comparator.contains() Comparator.contained_by() и Comparator.overlap(), например:

mytable.c.data.contains([1, 2])

Тип ARRAY может поддерживаться не во всех PostgreSQL DBAPI; в настоящее время известно, что он работает только в psycopg2.

Кроме того, тип ARRAY не работает непосредственно в сочетании с типом ENUM. Для обходного пути смотрите специальный тип Использование ENUM с ARRAY.

Обнаружение изменений в столбцах ARRAY при использовании ORM.

Тип ARRAY при использовании с SQLAlchemy ORM не обнаруживает мутации массива на месте. Для их обнаружения необходимо использовать расширение sqlalchemy.ext.mutable, используя класс MutableList:

from sqlalchemy.dialects.postgresql import ARRAY
from sqlalchemy.ext.mutable import MutableList

class SomeOrmClass(Base):
    # ...

    data = Column(MutableList.as_mutable(ARRAY(Integer)))

Это расширение позволит изменениям «на месте» в массиве, таким как .append(), создавать события, которые будут обнаружены блоком работы. Обратите внимание, что изменения элементов внутри массива, включая подмассивы, которые изменяются на месте, не обнаруживаются.

В качестве альтернативы можно назначить

См.также

ARRAY - базовый тип массива

array - выдает буквальное значение массива.

**Классный сиг

класс sqlalchemy.dialects.postgresql.ARRAY (sqlalchemy.types.ARRAY)

class Comparator

Определите операции сравнения для ARRAY.

Обратите внимание, что эти операции дополняют операции, предоставляемые базовым классом Comparator, включая Comparator.any() и Comparator.all().

**Классный сиг

класс sqlalchemy.dialects.postgresql.ARRAY.Comparator (sqlalchemy.types.Comparator)

method sqlalchemy.dialects.postgresql.ARRAY.Comparator.contained_by(other)

Булево выражение. Проверяет, являются ли элементы правильным подмножеством элементов выражения массива аргументов.

method sqlalchemy.dialects.postgresql.ARRAY.Comparator.contains(other, **kwargs)

Булево выражение. Проверяет, являются ли элементы супермножеством элементов выражения массива аргументов.

kwargs может быть ig

method sqlalchemy.dialects.postgresql.ARRAY.Comparator.overlap(other)

Булево выражение. Проверка наличия у массива общих элементов с выражением массива аргументов.

method sqlalchemy.dialects.postgresql.ARRAY.__init__(item_type: _TypeEngineArgument[Any], as_tuple: bool = False, dimensions: Optional[int] = None, zero_indexes: bool = False)

Сконструируйте ARRAY.

Например:

Column('myarray', ARRAY(Integer))

Аргументы таковы:

Параметры:
  • item_type – Тип данных элементов этого массива. Обратите внимание, что размерность здесь не имеет значения, поэтому многомерные массивы, такие как INTEGER[][], строятся как ARRAY(Integer), а не как ARRAY(ARRAY(Integer)) или подобные.

  • as_tuple=False – Укажите, следует ли преобразовывать возвращаемые результаты в кортежи из списков. DBAPI, такие как psycopg2, по умолчанию возвращают списки. Если возвращаются кортежи, результаты можно хэшировать.

  • dimensions – если нет, то ARRAY будет иметь фиксированное число размеров. Это приведет к тому, что DDL, создаваемый для этого ARRAY, будет включать точное количество скобочных предложений [], а также оптимизирует производительность типа в целом. Обратите внимание, что массивы PG всегда неявно «безразмерные», то есть они могут хранить любое количество размеров независимо от того, как они были объявлены.

  • zero_indexes=False – когда True, значения индексов будут преобразованы между нулевыми индексами Python и единичными индексами PostgreSQL, например, значение единицы будет добавлено ко всем значениям индексов перед передачей в базу данных.

class sqlalchemy.dialects.postgresql.BIT
class sqlalchemy.dialects.postgresql.BYTEA

Members

__init__()

method sqlalchemy.dialects.postgresql.BYTEA.__init__(length: Optional[int] = None)

наследуется от sqlalchemy.types.LargeBinary.__init__ метода LargeBinary

Создайте тип LargeBinary.

Параметры:

length – опционально, длина столбца для использования в DDL-запросах, для тех бинарных типов, которые принимают длину, например, тип MySQL BLOB.

class sqlalchemy.dialects.postgresql.CIDR
class sqlalchemy.dialects.postgresql.CITEXT

Укажите тип PostgreSQL CITEXT.

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

Members

__init__()

**Классный сиг

класс sqlalchemy.dialects.postgresql.CITEXT (sqlalchemy.types.TEXT)

method sqlalchemy.dialects.postgresql.CITEXT.__init__(length: Optional[int] = None, collation: Optional[str] = None)

наследуется от sqlalchemy.types.String.__init__ метода String

Создайте тип, удерживающий строку.

Параметры:
  • length – необязательный, длина столбца для использования в выражениях DDL и CAST. Может быть опущена, если не будет выдаваться CREATE TABLE. Некоторые базы данных могут требовать length для использования в DDL, и будут выдавать исключение при выдаче CREATE TABLE DDL, если включена VARCHAR без длины. Интерпретируется ли значение как байты или как символы, зависит от конкретной базы данных.

  • collation – Необязательно, collation на уровне столбцов для использования в выражениях DDL и CAST. Используется ключевое слово COLLATE, поддерживаемое SQLite, MySQL и PostgreSQL. Например: … sourcecode:: pycon+sql >>> from sqlalchemy import cast, select, String >>> print(select(cast(„some string“, String(collation=“utf8“)))) {printsql}SELECT CAST(:param_1 AS VARCHAR COLLATE utf8) AS anon_1 … примечание:: В большинстве случаев для Unicode или UnicodeText следует использовать типы данных Column, которые предполагают хранение неасксичных данных. Эти типы данных гарантируют, что в базе данных используются правильные типы.

class sqlalchemy.dialects.postgresql.DOMAIN

Представляет тип DOMAIN PostgreSQL.

Домен - это, по сути, тип данных с необязательными ограничениями, которые ограничивают допустимый набор значений. Например:

PositiveInt = DOMAIN(
    "pos_int", Integer, check="VALUE > 0", not_null=True
)

UsPostalCode = DOMAIN(
    "us_postal_code",
    Text,
    check="VALUE ~ '^\d{5}$' OR VALUE ~ '^\d{5}-\d{4}$'"
)

Дополнительные сведения см. в PostgreSQL documentation

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

**Классный сиг

класс sqlalchemy.dialects.postgresql.DOMAIN (sqlalchemy.dialects.postgresql.named_types.NamedType, sqlalchemy.types.SchemaType)

method sqlalchemy.dialects.postgresql.DOMAIN.__init__(name: str, data_type: _TypeEngineArgument[Any], *, collation: Optional[str] = None, default: Optional[Union[str, elements.TextClause]] = None, constraint_name: Optional[str] = None, not_null: Optional[bool] = None, check: Optional[str] = None, create_type: bool = True, **kw: Any)

Создайте ДОМАЙН.

Параметры:
  • name – имя домена

  • data_type – Тип данных, лежащий в основе домена. Он может включать спецификаторы массивов.

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

  • default – Пункт DEFAULT задает значение по умолчанию для столбцов типа данных домена. Значение по умолчанию должно быть строкой или значением text(). Если значение по умолчанию не указано, то значением по умолчанию будет нулевое значение.

  • constraint_name – Необязательное имя для ограничения. Если не указано, бэкенд генерирует имя.

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

  • check – Пункт CHECK задает ограничение целостности или тест, которому должны удовлетворять значения домена. Ограничение должно быть выражением, дающим булевский результат, которое может использовать ключевое слово VALUE для обозначения проверяемого значения. В отличие от PostgreSQL, в SQLAlchemy в настоящее время допускается только одно предложение проверки.

  • schema – необязательное имя схемы

  • metadata – необязательный объект MetaData, с которым этот DOMAIN будет непосредственно связан

  • create_type – По умолчанию имеет значение True. Указывает, что CREATE TYPE должно быть выдано, после дополнительной проверки на наличие типа, при создании родительской таблицы; и дополнительно, что DROP TYPE будет вызвано, когда таблица будет уничтожена.

method sqlalchemy.dialects.postgresql.DOMAIN.create(bind, checkfirst=True, **kw)

наследуется от NamedType.create() метода NamedType

Выдавать CREATE DDL для этого типа.

Параметры:
  • bind – подключаемый Engine, Connection или аналогичный объект для эмиссии SQL.

  • checkfirst – если True, то перед созданием сначала будет выполнен запрос к каталогу PG, чтобы убедиться, что тип еще не существует.

method sqlalchemy.dialects.postgresql.DOMAIN.drop(bind, checkfirst=True, **kw)

наследуется от NamedType.drop() метода NamedType

Выдавать DROP DDL для этого типа.

Параметры:
  • bind – подключаемый Engine, Connection или аналогичный объект для эмиссии SQL.

  • checkfirst – если True, сначала будет выполнен запрос к каталогу PG, чтобы проверить, существует ли тип на самом деле, прежде чем отбросить его.

class sqlalchemy.dialects.postgresql.DOUBLE_PRECISION

Тип SQL DOUBLE PRECISION.

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

См.также

Double - документация для базового типа.

**Классный сиг

класс sqlalchemy.dialects.postgresql.DOUBLE_PRECISION (sqlalchemy.types.Double)

method sqlalchemy.dialects.postgresql.DOUBLE_PRECISION.__init__(precision: Optional[int] = None, asdecimal: bool = False, decimal_return_scale: Optional[int] = None)

наследуется от sqlalchemy.types.Float.__init__ метода Float

Постройте поплавок.

Параметры:
  • precision – числовая точность для использования в DDL CREATE TABLE. Бэкенды должны пытаться обеспечить, чтобы эта точность указывала на число цифр для общего типа данных Float. … примечание:: Для бэкенда Oracle параметр Float.precision не принимается при рендеринге DDL, поскольку Oracle не поддерживает точность float, указанную как число десятичных знаков. Вместо этого используйте специфический для Oracle тип данных FLOAT и укажите параметр FLOAT.binary_precision. Это новое в версии 2.0 SQLAlchemy. Чтобы создать базу данных ag

  • asdecimal – тот же флаг, что и у Numeric, но по умолчанию имеет значение False. Обратите внимание, что установка этого флага в значение True приводит к преобразованию с плавающей точкой.

  • decimal_return_scale – Масштаб по умолчанию, используемый при преобразовании значений с плавающей точкой в десятичные числа Python. Значения с плавающей точкой обычно намного длиннее из-за неточности десятичных дробей, а большинство типов баз данных с плавающей точкой не имеют понятия «масштаб», поэтому по умолчанию тип float ищет первые десять десятичных знаков при преобразовании. Указание этого значения отменяет эту длину. Обратите внимание, что типы MySQL float, которые включают «масштаб», будут использовать «масштаб» по умолчанию для decimal_return_scale, если не указано иное.

class sqlalchemy.dialects.postgresql.ENUM

Тип PostgreSQL ENUM.

Это подкласс Enum, который включает поддержку PG CREATE TYPE и DROP TYPE.

Когда используется встроенный тип Enum и флаг Enum.native_enum оставлен по умолчанию True, бэкенд PostgreSQL будет использовать тип ENUM в качестве реализации, поэтому будут использоваться специальные правила создания/удаления.

Поведение ENUM при создании/удалении неизбежно запутано из-за неудобных отношений типа ENUM с родительской таблицей, поскольку он может «принадлежать» только одной таблице, а может быть разделен между многими таблицами.

При использовании Enum или ENUM способом «inline», CREATE TYPE и DROP TYPE выдаются в соответствии с тем, когда вызываются методы Table.create() и Table.drop():

table = Table('sometable', metadata,
    Column('some_enum', ENUM('a', 'b', 'c', name='myenum'))
)

table.create(engine)  # will emit CREATE ENUM and CREATE TABLE
table.drop(engine)  # will emit DROP TABLE and DROP ENUM

Чтобы использовать общий перечислимый тип между несколькими таблицами, лучше всего объявить Enum или ENUM независимо и связать его с самим объектом MetaData:

my_enum = ENUM('a', 'b', 'c', name='myenum', metadata=metadata)

t1 = Table('sometable_one', metadata,
    Column('some_enum', myenum)
)

t2 = Table('sometable_two', metadata,
    Column('some_enum', myenum)
)

При использовании этого шаблона все равно необходимо соблюдать осторожность на уровне создания отдельных таблиц. Создание CREATE TABLE без указания checkfirst=True по-прежнему будет вызывать проблемы:

t1.create(engine) # will fail: no such type 'myenum'

Если мы укажем checkfirst=True, операция создания на уровне отдельных таблиц будет проверять наличие ENUM и создавать, если не существует:

# will check if enum exists, and emit CREATE TYPE if not
t1.create(engine, checkfirst=True)

При использовании ENUM-типа на уровне метаданных, тип всегда будет создаваться и уничтожаться, если вызывается либо общий для метаданных метод create/drop:

metadata.create_all(engine)  # will emit CREATE TYPE
metadata.drop_all(engine)  # will emit DROP TYPE

Тип также может быть создан и сброшен напрямую:

my_enum.create(engine)
my_enum.drop(engine)

**Классный сиг

class sqlalchemy.dialects.postgresql.ENUM (sqlalchemy.dialects.postgresql.named_types.NamedType, sqlalchemy.types.NativeForEmulated, sqlalchemy.types.Enum)

method sqlalchemy.dialects.postgresql.ENUM.__init__(*enums, name: Optional[Union[str, _NoArg]] = _NoArg.NO_ARG, create_type: bool = True, **kw)

Сконструируйте ENUM.

Аргументы те же, что и у Enum, но включают следующие параметры.

Параметры:

create_type – По умолчанию имеет значение True. Указывает, что CREATE TYPE должен быть выдан, после опциональной проверки на наличие типа, при создании родительской таблицы; и дополнительно, что DROP TYPE будет вызван, когда таблица будет уничтожена. При False проверка не выполняется и не выдается CREATE TYPE или DROP TYPE, если только ENUM.create() или ENUM.drop() не вызываются напрямую. Установка в False полезна при вызове схемы создания SQL файла без доступа к реальной базе данных - методы ENUM.create() и ENUM.drop() могут быть использованы для эмиссии SQL в целевую привязку.

method sqlalchemy.dialects.postgresql.ENUM.create(bind=None, checkfirst=True)

Излучайте CREATE TYPE для этого ENUM.

Если базовый диалект не поддерживает PostgreSQL CREATE TYPE, никаких действий не предпринимается.

Параметры:
  • bind – подключаемый Engine, Connection или аналогичный объект для эмиссии SQL.

  • checkfirst – если True, то перед созданием сначала будет выполнен запрос к каталогу PG, чтобы убедиться, что тип еще не существует.

method sqlalchemy.dialects.postgresql.ENUM.drop(bind=None, checkfirst=True)

Излучайте DROP TYPE для этого ENUM.

Если базовый диалект не поддерживает PostgreSQL DROP TYPE, никаких действий не предпринимается.

Параметры:
  • bind – подключаемый Engine, Connection или аналогичный объект для эмиссии SQL.

  • checkfirst – если True, сначала будет выполнен запрос к каталогу PG, чтобы проверить, существует ли тип на самом деле, прежде чем отбросить его.

class sqlalchemy.dialects.postgresql.HSTORE

Представляет собой тип PostgreSQL HSTORE.

Тип HSTORE хранит словари, содержащие строки, например:

data_table = Table('data_table', metadata,
    Column('id', Integer, primary_key=True),
    Column('data', HSTORE)
)

with engine.connect() as conn:
    conn.execute(
        data_table.insert(),
        data = {"key1": "value1", "key2": "value2"}
    )

HSTORE обеспечивает широкий спектр операций, включая:

  • Индексные операции:

    data_table.c.data['some key'] == 'some value'
  • Операции по удержанию:

    data_table.c.data.has_key('some key')
    
    data_table.c.data.has_all(['one', 'two', 'three'])
  • Конкатенация:

    data_table.c.data + {"k1": "v1"}

Полный список специальных методов приведен в comparator_factory.

Обнаружение изменений в колонках HSTORE при использовании ORM.

Для использования с SQLAlchemy ORM может оказаться желательным объединить использование HSTORE со словарем MutableDict, который теперь является частью расширения sqlalchemy.ext.mutable. Это расширение позволит «на месте» вносить изменения в словарь, например, добавлять новые ключи или заменять/удалять существующие ключи в/из текущего словаря, для создания событий, которые будут обнаружены блоком работы:

from sqlalchemy.ext.mutable import MutableDict

class MyClass(Base):
    __tablename__ = 'data_table'

    id = Column(Integer, primary_key=True)
    data = Column(MutableDict.as_mutable(HSTORE))

my_object = session.query(MyClass).one()

# in-place mutation, requires Mutable extension
# in order for the ORM to detect
my_object.data['some_key'] = 'some value'

session.commit()

Когда расширение sqlalchemy.ext.mutable не используется, ORM не будет предупрежден о любых изменениях в содержимом существующего словаря, пока значение словаря не будет переназначено.

См.также

hstore - рендеринг функции PostgreSQL hstore().

class Comparator

Определите операции сравнения для HSTORE.

**Классный сиг

класс sqlalchemy.dialects.postgresql.HSTORE.Comparator (sqlalchemy.types.Comparator, sqlalchemy.types.Comparator)

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.array()

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

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.contained_by(other)

Булево выражение. Проверяет, являются ли ключи правильным подмножеством ключей аргумента jsonb-выражения.

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.contains(other, **kwargs)

Булево выражение. Проверяет, являются ли ключи (или массив) надмножеством/содержат ли ключи аргумента jsonb выражения.

kwargs может быть ig

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.defined(key)

Булево выражение. Проверяет наличие не-NULL значения для ключа. Обратите внимание, что ключ может быть выражением SQLA.

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.delete(key)

Выражение HStore. Возвращает содержимое данного hstore с удаленным заданным ключом. Обратите внимание, что ключ может быть выражением SQLA.

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.has_all(other)

Булево выражение. Проверка наличия всех ключей в jsonb

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.has_any(other)

Булево выражение. Проверка наличия любого ключа в jsonb

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.has_key(other)

Булево выражение. Проверка на наличие ключа. Обратите внимание, что ключ может быть выражением SQLA.

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.keys()

Выражение текстового массива. Возвращает массив ключей.

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.matrix()

Выражение текстового массива. Возвращает массив пар [ключ, значение].

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.slice(array)

Выражение HStore. Возвращает подмножество hstore, заданное массивом ключей.

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.vals()

Выражение текстового массива. Возвращает массив значений.

method sqlalchemy.dialects.postgresql.HSTORE.__init__(text_type=None)

Создайте новый HSTORE.

Параметры:

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

method sqlalchemy.dialects.postgresql.HSTORE.bind_processor(dialect)

Возвращает функцию преобразования для обработки значений привязки.

Возвращает вызываемый объект, который получает значение параметра bind в качестве единственного позиционного аргумента и возвращает значение для отправки в DB-API.

Если обработка не требуется, метод должен вернуть None.

Примечание

Этот метод вызывается только относительно объекта типа, специфичного для диалекта, который часто является частным для используемого диалекта и не является тем же самым объектом типа, что и общедоступный, что означает, что невозможно подклассифицировать класс TypeEngine, чтобы обеспечить альтернативный метод TypeEngine.bind_processor(), если только не подклассифицировать класс UserDefinedType явно.

Чтобы обеспечить альтернативное поведение для TypeEngine.bind_processor(), реализуйте класс TypeDecorator и обеспечьте реализацию TypeDecorator.process_bind_param().

Параметры:

dialect – Используемый диалектный экземпляр.

attribute sqlalchemy.dialects.postgresql.HSTORE.comparator_factory

alias of Comparator

attribute sqlalchemy.dialects.postgresql.HSTORE.hashable = False

Флаг, если False, означает, что значения этого типа не хэшируются.

Используется ORM при уникализации списков результатов.

method sqlalchemy.dialects.postgresql.HSTORE.result_processor(dialect, coltype)

Возвращает функцию преобразования для обработки значений строки результата.

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

Если обработка не требуется, метод должен вернуть None.

Примечание

Этот метод вызывается только относительно объекта типа, специфичного для диалекта, который часто является частным для используемого диалекта и не является тем же самым объектом типа, что и общедоступный, что означает, что невозможно подклассифицировать класс TypeEngine, чтобы обеспечить альтернативный метод TypeEngine.result_processor(), если только не подклассифицировать класс UserDefinedType явно.

Чтобы обеспечить альтернативное поведение для TypeEngine.result_processor(), реализуйте класс TypeDecorator и обеспечьте реализацию TypeDecorator.process_result_value().

Параметры:
  • dialect – Используемый диалектный экземпляр.

  • coltype – DBAPI coltype аргумент, полученный в cursor.description.

class sqlalchemy.dialects.postgresql.INET
class sqlalchemy.dialects.postgresql.INTERVAL

PostgreSQL Тип INTERVAL.

Members

__init__()

**Классный сиг

класс sqlalchemy.dialects.postgresql.INTERVAL (sqlalchemy.types.NativeForEmulated, sqlalchemy.types._AbstractInterval)

method sqlalchemy.dialects.postgresql.INTERVAL.__init__(precision: Optional[int] = None, fields: Optional[str] = None) None

Постройте интервал.

Параметры:
  • precision – необязательное значение точности целого числа

  • fields – спецификатор строковых полей. позволяет ограничить хранение полей, например, "YEAR", "MONTH", "DAY TO HOUR" и т.д. … versionadded:: 1.2

class sqlalchemy.dialects.postgresql.JSON

Представляет тип PostgreSQL JSON.

JSON используется автоматически, когда базовый тип данных JSON используется против бэкенда PostgreSQL, однако базовый тип данных JSON не предоставляет Python-доступ для специфических для PostgreSQL методов сравнения, таких как Comparator.astext(); кроме того, для использования PostgreSQL JSONB необходимо явно использовать тип данных JSONB.

См.также

JSON - основная документация по общему кроссплатформенному типу данных JSON.

Операторы, предоставляемые PostgreSQL-версией JSON, включают:

  • Операции с индексами (оператор ->):

    data_table.c.data['some key']
    
    data_table.c.data[5]
  • Индексные операции, возвращающие текст (оператор ->>):

    data_table.c.data['some key'].astext == 'some value'

    Обратите внимание, что эквивалентная функциональность доступна через аксессор Comparator.as_string.

  • Операции с индексами с помощью CAST (эквивалентно CAST(col ->> ['some key'] AS <type>)):

    data_table.c.data['some key'].astext.cast(Integer) == 5

    Обратите внимание, что эквивалентная функциональность доступна через Comparator.as_integer и аналогичные аксессоры.

  • Операции с индексом пути (оператор #>):

    data_table.c.data[('key_1', 'key_2', 5, ..., 'key_n')]
  • Операции с индексом пути, возвращающие текст (оператор #>>):

    data_table.c.data[('key_1', 'key_2', 5, ..., 'key_n')].astext == 'some value'

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

Пользовательские сериализаторы и десериализаторы задаются на уровне диалекта, то есть с помощью create_engine(). Причина в том, что при использовании psycopg2 DBAPI позволяет использовать сериализаторы только на уровне каждого курсора или каждого соединения. Например:

engine = create_engine("postgresql+psycopg2://scott:tiger@localhost/test",
                        json_serializer=my_serialize_fn,
                        json_deserializer=my_deserialize_fn
                )

При использовании диалекта psycopg2, json_deserializer регистрируется в базе данных с помощью psycopg2.extras.register_default_json.

См.также

JSON - тип JSON основного уровня

JSONB

**Классный сиг

класс sqlalchemy.dialects.postgresql.JSON (sqlalchemy.types.JSON)

class Comparator

Определите операции сравнения для JSON.

**Классный сиг

класс sqlalchemy.dialects.postgresql.JSON.Comparator (sqlalchemy.types.Comparator)

attribute sqlalchemy.dialects.postgresql.JSON.Comparator.astext

Для индексированного выражения используйте преобразование «astext» (например, «->>») при отображении в SQL.

Например:

select(data_table.c.data['some key'].astext)

См.также

ColumnElement.cast()

method sqlalchemy.dialects.postgresql.JSON.__init__(none_as_null=False, astext_type=None)

Сконструируйте тип JSON.

Параметры:
  • none_as_null – если True, сохранять значение None как значение SQL NULL, а не JSON-кодировку null. Обратите внимание, что когда этот флаг равен False, конструкция null() все еще может быть использована для сохранения значения NULL:: from sqlalchemy import null conn.execute(table.insert(), data=null()) … seealso:: JSON.NULL

  • astext_type – тип, используемый для аксессора Comparator.astext на индексированных атрибутах. По умолчанию используется Text.

attribute sqlalchemy.dialects.postgresql.JSON.comparator_factory

alias of Comparator

class sqlalchemy.dialects.postgresql.JSONB

Представляет тип PostgreSQL JSONB.

Тип JSONB хранит данные произвольного формата JSONB, например:

data_table = Table('data_table', metadata,
    Column('id', Integer, primary_key=True),
    Column('data', JSONB)
)

with engine.connect() as conn:
    conn.execute(
        data_table.insert(),
        data = {"key1": "value1", "key2": "value2"}
    )

Тип JSONB включает все операции, предоставляемые типом JSON, включая те же самые поведения для операций индексирования. Он также добавляет дополнительные операторы, специфичные для JSONB, включая Comparator.has_key(), Comparator.has_all(), Comparator.has_any(), Comparator.contains(), Comparator.contained_by(), Comparator.delete_path(), Comparator.path_exists() и Comparator.path_match().

Как и тип JSON, тип JSONB не обнаруживает изменений на месте при использовании с ORM, если не используется расширение sqlalchemy.ext.mutable.

Пользовательские сериализаторы и десериализаторы совместно используются с классом JSON, используя аргументы ключевых слов json_serializer и json_deserializer. Они должны быть указаны на уровне диалекта с помощью create_engine(). При использовании psycopg2 сериализаторы ассоциируются с типом jsonb с помощью psycopg2.extras.register_default_jsonb на основе каждого соединения, точно так же, как psycopg2.extras.register_default_json используется для регистрации этих обработчиков с типом json.

См.также

JSON

class Comparator

Определите операции сравнения для JSON.

**Классный сиг

класс sqlalchemy.dialects.postgresql.JSONB.Comparator (sqlalchemy.dialects.postgresql.json.Comparator)

method sqlalchemy.dialects.postgresql.JSONB.Comparator.contained_by(other)

Булево выражение. Проверяет, являются ли ключи правильным подмножеством ключей аргумента jsonb-выражения.

method sqlalchemy.dialects.postgresql.JSONB.Comparator.contains(other, **kwargs)

Булево выражение. Проверяет, являются ли ключи (или массив) надмножеством/содержат ли ключи аргумента jsonb выражения.

kwargs может быть ig

method sqlalchemy.dialects.postgresql.JSONB.Comparator.delete_path(array)

Выражение JSONB. Удаляет поле или элемент массива, указанный в массиве аргументов.

Входными данными может быть список строк, которые будут принудительно преобразованы в ARRAY или экземпляр _postgres.array().

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

method sqlalchemy.dialects.postgresql.JSONB.Comparator.has_all(other)

Булево выражение. Проверка наличия всех ключей в jsonb

method sqlalchemy.dialects.postgresql.JSONB.Comparator.has_any(other)

Булево выражение. Проверка наличия любого ключа в jsonb

method sqlalchemy.dialects.postgresql.JSONB.Comparator.has_key(other)

Булево выражение. Проверка на наличие ключа. Обратите внимание, что ключ может быть выражением SQLA.

method sqlalchemy.dialects.postgresql.JSONB.Comparator.path_exists(other)

Булево выражение. Проверка наличия элемента, заданного аргументом JSONPath выражения.

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

method sqlalchemy.dialects.postgresql.JSONB.Comparator.path_match(other)

Булево выражение. Проверяет, совпадает ли предикат JSONPath, заданный аргументом JSONPath expression.

Учитывается только первый пункт результата.

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

attribute sqlalchemy.dialects.postgresql.JSONB.comparator_factory

alias of Comparator

class sqlalchemy.dialects.postgresql.JSONPATH

JSON Тип пути.

Обычно это требуется для приведения литеральных значений к json-пути при использовании функции json search like, например, jsonb_path_query_array или jsonb_path_exists:

stmt = sa.select(
    sa.func.jsonb_path_query_array(
        table.c.jsonb_col, cast("$.address.id", JSONPATH)
    )
)

**Классный сиг

класс sqlalchemy.dialects.postgresql.JSONPATH (sqlalchemy.dialects.postgresql.json.JSONPathType)

class sqlalchemy.dialects.postgresql.MACADDR
class sqlalchemy.dialects.postgresql.MACADDR8
class sqlalchemy.dialects.postgresql.MONEY

Укажите тип PostgreSQL MONEY.

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

По этой причине может оказаться предпочтительным обеспечить преобразование в числовой тип данных валюты с помощью TypeDecorator:

import re
import decimal
from sqlalchemy import Dialect
from sqlalchemy import TypeDecorator

class NumericMoney(TypeDecorator):
    impl = MONEY

    def process_result_value(
        self, value: Any, dialect: Dialect
    ) -> None:
        if value is not None:
            # adjust this for the currency and numeric
            m = re.match(r"\$([\d.]+)", value)
            if m:
                value = decimal.Decimal(m.group(1))
        return value

Альтернативно, преобразование может быть применено как CAST с использованием метода TypeDecorator.column_expression() следующим образом:

import decimal
from sqlalchemy import cast
from sqlalchemy import TypeDecorator

class NumericMoney(TypeDecorator):
    impl = MONEY

    def column_expression(self, column: Any):
        return cast(column, Numeric())

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

class sqlalchemy.dialects.postgresql.OID

Укажите тип OID PostgreSQL.

class sqlalchemy.dialects.postgresql.REAL

Тип SQL REAL.

См.также

Float - документация для базового типа.

**Классный сиг

класс sqlalchemy.dialects.postgresql.REAL (sqlalchemy.types.Float)

method sqlalchemy.dialects.postgresql.REAL.__init__(precision: Optional[int] = None, asdecimal: bool = False, decimal_return_scale: Optional[int] = None)

наследуется от sqlalchemy.types.Float.__init__ метода Float

Постройте поплавок.

Параметры:
  • precision – числовая точность для использования в DDL CREATE TABLE. Бэкенды должны пытаться обеспечить, чтобы эта точность указывала на число цифр для общего типа данных Float. … примечание:: Для бэкенда Oracle параметр Float.precision не принимается при рендеринге DDL, поскольку Oracle не поддерживает точность float, указанную как число десятичных знаков. Вместо этого используйте специфический для Oracle тип данных FLOAT и укажите параметр FLOAT.binary_precision. Это новое в версии 2.0 SQLAlchemy. Чтобы создать базу данных ag

  • asdecimal – тот же флаг, что и у Numeric, но по умолчанию имеет значение False. Обратите внимание, что установка этого флага в значение True приводит к преобразованию с плавающей точкой.

  • decimal_return_scale – Масштаб по умолчанию, используемый при преобразовании значений с плавающей точкой в десятичные числа Python. Значения с плавающей точкой обычно намного длиннее из-за неточности десятичных дробей, а большинство типов баз данных с плавающей точкой не имеют понятия «масштаб», поэтому по умолчанию тип float ищет первые десять десятичных знаков при преобразовании. Указание этого значения отменяет эту длину. Обратите внимание, что типы MySQL float, которые включают «масштаб», будут использовать «масштаб» по умолчанию для decimal_return_scale, если не указано иное.

class sqlalchemy.dialects.postgresql.REGCONFIG

Укажите тип PostgreSQL REGCONFIG.

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

class sqlalchemy.dialects.postgresql.REGCLASS

Укажите тип PostgreSQL REGCLASS.

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

class sqlalchemy.dialects.postgresql.TIMESTAMP

Укажите тип PostgreSQL TIMESTAMP.

Members

__init__()

method sqlalchemy.dialects.postgresql.TIMESTAMP.__init__(timezone: bool = False, precision: Optional[int] = None) None

Постройте TIMESTAMP.

Параметры:
  • timezone – булево значение, если присутствует часовой пояс, по умолчанию False

  • precision – необязательное целочисленное значение точности .. versionadded:: 1.4

class sqlalchemy.dialects.postgresql.TIME

PostgreSQL Тип времени.

Members

__init__()

**Классный сиг

класс sqlalchemy.dialects.postgresql.TIME (sqlalchemy.types.TIME)

method sqlalchemy.dialects.postgresql.TIME.__init__(timezone: bool = False, precision: Optional[int] = None) None

Постройте ВРЕМЯ.

Параметры:
  • timezone – булево значение, если присутствует часовой пояс, по умолчанию False

  • precision – необязательное целочисленное значение точности .. versionadded:: 1.4

class sqlalchemy.dialects.postgresql.TSQUERY

Укажите тип PostgreSQL TSQUERY.

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

class sqlalchemy.dialects.postgresql.TSVECTOR

Тип TSVECTOR реализует тип текстового поиска PostgreSQL TSVECTOR.

Его можно использовать для выполнения полнотекстовых запросов к документам на естественном языке.

class sqlalchemy.dialects.postgresql.UUID

Представляет тип SQL UUID.

Это SQL-нативная форма базы данных Uuid ag

Тип данных UUID работает только с базами данных, которые имеют тип данных SQL с именем UUID. Он не будет работать для бэкендов, которые не имеют такого типа с точным названием, включая SQL Server. Для бэкенд-аг

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

См.также

Uuid

**Классный сиг

класс sqlalchemy.dialects.postgresql.UUID (sqlalchemy.types.Uuid, sqlalchemy.types.NativeForEmulated)

method sqlalchemy.dialects.postgresql.UUID.__init__(as_uuid: bool = True)

Сконструируйте тип UUID.

Параметры:

as_uuid=True – если True, то значения будут интерпретироваться как объекты Python uuid, конвертируемые в/из строки через DBAPI. … versionchanged: 2.0 as_uuid теперь по умолчанию True.

class sqlalchemy.dialects.postgresql.INT4RANGE

Представляет тип PostgreSQL INT4RANGE.

class sqlalchemy.dialects.postgresql.INT8RANGE

Представляет тип PostgreSQL INT8RANGE.

class sqlalchemy.dialects.postgresql.NUMRANGE

Представляет тип PostgreSQL NUMRANGE.

class sqlalchemy.dialects.postgresql.DATERANGE

Представляет тип PostgreSQL DATERANGE.

class sqlalchemy.dialects.postgresql.TSRANGE

Представляет тип PostgreSQL TSRANGE.

class sqlalchemy.dialects.postgresql.TSTZRANGE

Представляет тип PostgreSQL TSTZRANGE.

class sqlalchemy.dialects.postgresql.INT4MULTIRANGE

Представляет тип PostgreSQL INT4MULTIRANGE.

class sqlalchemy.dialects.postgresql.INT8MULTIRANGE

Представляет тип PostgreSQL INT8MULTIRANGE.

class sqlalchemy.dialects.postgresql.NUMMULTIRANGE

Представляет тип PostgreSQL NUMMULTIRANGE.

class sqlalchemy.dialects.postgresql.DATEMULTIRANGE

Представляет тип PostgreSQL DATEMULTIRANGE.

class sqlalchemy.dialects.postgresql.TSMULTIRANGE

Представляет тип PostgreSQL TSRANGE.

class sqlalchemy.dialects.postgresql.TSTZMULTIRANGE

Представляет тип PostgreSQL TSTZRANGE.

Элементы и функции SQL PostgreSQL

Object Name Description

aggregate_order_by

Представляет собой агрегатный порядок PostgreSQL по выражению.

All(other, arrexpr[, operator])

Синоним метода ARRAY-level Comparator.all(). Подробности см. в этом методе.

Any(other, arrexpr[, operator])

Синоним метода ARRAY-level Comparator.any(). Подробности см. в этом методе.

array

Литерал PostgreSQL ARRAY.

array_agg(*arg, **kw)

Специфическая для PostgreSQL форма array_agg, обеспечивающая возврат типа ARRAY, а не простого ARRAY, если не передан явный type_.

hstore

Создайте значение hstore в выражении SQL с помощью функции PostgreSQL hstore().

phraseto_tsquery

SQL-функция PostgreSQL phraseto_tsquery.

plainto_tsquery

SQL-функция PostgreSQL plainto_tsquery.

to_tsquery

SQL-функция PostgreSQL to_tsquery.

to_tsvector

SQL-функция PostgreSQL to_tsvector.

ts_headline

SQL-функция PostgreSQL ts_headline.

websearch_to_tsquery

SQL-функция PostgreSQL websearch_to_tsquery.

class sqlalchemy.dialects.postgresql.aggregate_order_by

Представляет собой агрегатный порядок PostgreSQL по выражению.

Например:

from sqlalchemy.dialects.postgresql import aggregate_order_by
expr = func.array_agg(aggregate_order_by(table.c.a, table.c.b.desc()))
stmt = select(expr)

будет представлять собой выражение:

SELECT array_agg(a ORDER BY b DESC) FROM table;

Аналогично:

expr = func.string_agg(
    table.c.a,
    aggregate_order_by(literal_column("','"), table.c.a)
)
stmt = select(expr)

Будет представлять:

SELECT string_agg(a, ',' ORDER BY a) FROM table;

Изменено в версии 1.2.13: - the ORDER BY argument may be multiple terms

См.также

array_agg

class sqlalchemy.dialects.postgresql.array

Литерал PostgreSQL ARRAY.

Это используется для создания литералов ARRAY в выражениях SQL, например:

from sqlalchemy.dialects.postgresql import array
from sqlalchemy.dialects import postgresql
from sqlalchemy import select, func

stmt = select(array([1,2]) + array([3,4,5]))

print(stmt.compile(dialect=postgresql.dialect()))

Производит SQL:

SELECT ARRAY[%(param_1)s, %(param_2)s] ||
    ARRAY[%(param_3)s, %(param_4)s, %(param_5)s]) AS anon_1

Экземпляр array всегда будет иметь тип данных ARRAY. Внутренний» тип массива определяется по присутствующим значениям, если только не передан аргумент ключевого слова type_:

array(['foo', 'bar'], type_=CHAR)

Многомерные массивы создаются путем вложения конструкций array. Размерность конечного типа ARRAY вычисляется путем рекурсивного сложения размерностей внутренних типов ARRAY:

stmt = select(
    array([
        array([1, 2]), array([3, 4]), array([column('q'), column('x')])
    ])
)
print(stmt.compile(dialect=postgresql.dialect()))

Производит:

SELECT ARRAY[ARRAY[%(param_1)s, %(param_2)s],
ARRAY[%(param_3)s, %(param_4)s], ARRAY[q, x]] AS anon_1

Добавлено в версии 1.3.6: добавлена поддержка литералов многомерных массивов

См.также

ARRAY

**Классный сиг

класс sqlalchemy.dialects.postgresql.array (sqlalchemy.sql.expression.ExpressionClauseList)

function sqlalchemy.dialects.postgresql.array_agg(*arg, **kw)

Специфическая для PostgreSQL форма array_agg, обеспечивающая возврат типа ARRAY, а не простого ARRAY, если не передан явный type_.

function sqlalchemy.dialects.postgresql.Any(other, arrexpr, operator=<built-in function eq>)

Синоним метода ARRAY-level Comparator.any(). Подробности см. в этом методе.

function sqlalchemy.dialects.postgresql.All(other, arrexpr, operator=<built-in function eq>)

Синоним метода ARRAY-level Comparator.all(). Подробности см. в этом методе.

class sqlalchemy.dialects.postgresql.hstore

Создайте значение hstore в выражении SQL с помощью функции PostgreSQL hstore().

Функция hstore принимает один или два аргумента, как описано в документации PostgreSQL.

Например:

from sqlalchemy.dialects.postgresql import array, hstore

select(hstore('key1', 'value1'))

select(
    hstore(
        array(['key1', 'key2', 'key3']),
        array(['value1', 'value2', 'value3'])
    )
)

См.также

HSTORE - тип данных PostgreSQL HSTORE.

Members

inherit_cache, type

attribute sqlalchemy.dialects.postgresql.hstore.inherit_cache: Optional[bool] = True

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

По умолчанию атрибут имеет значение None, что указывает на то, что конструкция еще не приняла во внимание целесообразность ее участия в кэшировании; функционально это эквивалентно установке значения False, за исключением того, что при этом выдается предупреждение.

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

См.также

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

attribute sqlalchemy.dialects.postgresql.hstore.type

alias of HSTORE

class sqlalchemy.dialects.postgresql.to_tsvector

SQL-функция PostgreSQL to_tsvector.

Эта функция применяет автоматическое приведение аргумента REGCONFIG, чтобы автоматически использовать тип данных REGCONFIG, и применяет тип возврата TSVECTOR.

Если диалект PostgreSQL был импортирован либо вызовом from sqlalchemy.dialects import postgresql, либо созданием движка PostgreSQL с помощью create_engine("postgresql..."), to_tsvector будет использоваться автоматически при вызове sqlalchemy.func.to_tsvector(), обеспечивая использование правильных обработчиков аргументов и типов возврата во время компиляции и выполнения.

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

**Классный сиг

класс sqlalchemy.dialects.postgresql.to_tsvector (sqlalchemy.dialects.postgresql.ext._regconfig_fn)

class sqlalchemy.dialects.postgresql.to_tsquery

SQL-функция PostgreSQL to_tsquery.

Эта функция применяет автоматическое приведение аргумента REGCONFIG, чтобы автоматически использовать тип данных REGCONFIG, и применяет тип возврата TSQUERY.

Если диалект PostgreSQL был импортирован либо вызовом from sqlalchemy.dialects import postgresql, либо созданием движка PostgreSQL с помощью create_engine("postgresql..."), to_tsquery будет использоваться автоматически при вызове sqlalchemy.func.to_tsquery(), обеспечивая использование правильных обработчиков аргументов и типов возврата во время компиляции и выполнения.

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

**Классный сиг

класс sqlalchemy.dialects.postgresql.to_tsquery (sqlalchemy.dialects.postgresql.ext._regconfig_fn)

class sqlalchemy.dialects.postgresql.plainto_tsquery

SQL-функция PostgreSQL plainto_tsquery.

Эта функция применяет автоматическое приведение аргумента REGCONFIG, чтобы автоматически использовать тип данных REGCONFIG, и применяет тип возврата TSQUERY.

Если диалект PostgreSQL был импортирован либо вызовом from sqlalchemy.dialects import postgresql, либо созданием движка PostgreSQL с помощью create_engine("postgresql..."), plainto_tsquery будет использоваться автоматически при вызове sqlalchemy.func.plainto_tsquery(), обеспечивая использование правильных обработчиков аргументов и типов возврата во время компиляции и выполнения.

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

**Классный сиг

класс sqlalchemy.dialects.postgresql.plainto_tsquery (sqlalchemy.dialects.postgresql.ext._regconfig_fn)

class sqlalchemy.dialects.postgresql.phraseto_tsquery

SQL-функция PostgreSQL phraseto_tsquery.

Эта функция применяет автоматическое приведение аргумента REGCONFIG, чтобы автоматически использовать тип данных REGCONFIG, и применяет тип возврата TSQUERY.

Если диалект PostgreSQL был импортирован либо вызовом from sqlalchemy.dialects import postgresql, либо созданием движка PostgreSQL с помощью create_engine("postgresql..."), phraseto_tsquery будет использоваться автоматически при вызове sqlalchemy.func.phraseto_tsquery(), обеспечивая использование правильных обработчиков аргументов и типов возврата во время компиляции и выполнения.

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

**Классный сиг

класс sqlalchemy.dialects.postgresql.phraseto_tsquery (sqlalchemy.dialects.postgresql.ext._regconfig_fn)

class sqlalchemy.dialects.postgresql.websearch_to_tsquery

SQL-функция PostgreSQL websearch_to_tsquery.

Эта функция применяет автоматическое приведение аргумента REGCONFIG, чтобы автоматически использовать тип данных REGCONFIG, и применяет тип возврата TSQUERY.

Если диалект PostgreSQL был импортирован либо вызовом from sqlalchemy.dialects import postgresql, либо созданием движка PostgreSQL с помощью create_engine("postgresql..."), websearch_to_tsquery будет использоваться автоматически при вызове sqlalchemy.func.websearch_to_tsquery(), обеспечивая использование правильных обработчиков аргументов и типов возврата во время компиляции и выполнения.

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

**Классный сиг

класс sqlalchemy.dialects.postgresql.websearch_to_tsquery (sqlalchemy.dialects.postgresql.ext._regconfig_fn)

class sqlalchemy.dialects.postgresql.ts_headline

SQL-функция PostgreSQL ts_headline.

Эта функция применяет автоматическое приведение аргумента REGCONFIG, чтобы автоматически использовать тип данных REGCONFIG, и применяет тип возврата TEXT.

Если диалект PostgreSQL был импортирован либо вызовом from sqlalchemy.dialects import postgresql, либо созданием движка PostgreSQL с помощью create_engine("postgresql..."), ts_headline будет использоваться автоматически при вызове sqlalchemy.func.ts_headline(), обеспечивая использование правильных обработчиков аргументов и типов возврата во время компиляции и выполнения.

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

**Классный сиг

класс sqlalchemy.dialects.postgresql.ts_headline (sqlalchemy.dialects.postgresql.ext._regconfig_fn)

Типы ограничений PostgreSQL

SQLAlchemy поддерживает ограничения PostgreSQL EXCLUDE с помощью класса ExcludeConstraint:

Object Name Description

ExcludeConstraint

Ограничение EXCLUDE на уровне таблицы.

class sqlalchemy.dialects.postgresql.ExcludeConstraint

Ограничение EXCLUDE на уровне таблицы.

Определяет ограничение EXCLUDE, как описано в PostgreSQL documentation.

Members

__init__()

method sqlalchemy.dialects.postgresql.ExcludeConstraint.__init__(*elements, **kw)

Создайте объект ExcludeConstraint.

Например:

const = ExcludeConstraint(
    (Column('period'), '&&'),
    (Column('group'), '='),
    where=(Column('group') != 'some group'),
    ops={'group': 'my_operator_class'}
)

Ограничение обычно встраивается непосредственно в конструкцию Table или добавляется позже с помощью append_constraint():

some_table = Table(
    'some_table', metadata,
    Column('id', Integer, primary_key=True),
    Column('period', TSRANGE()),
    Column('group', String)
)

some_table.append_constraint(
    ExcludeConstraint(
        (some_table.c.period, '&&'),
        (some_table.c.group, '='),
        where=some_table.c.group != 'some group',
        name='some_table_excl_const',
        ops={'group': 'my_operator_class'}
    )
)
Параметры:
  • *elements – Последовательность из двух кортежей вида (column, operator), где «column» - это либо объект Column, либо элемент выражения SQL (например. func.int8range(table.from, table.to)) или имя столбца как строка, а «operator» - строка, содержащая оператор для использования (например, «&&» or «=»). In order to specify a column name when a Column object is not available, while ensuring that any necessary quoting rules take effect, an ad-hoc Column or column() object should be used. The column may also be a string SQL expression when passed as literal_column() or text()).

  • name – Необязательно, имя этого ограничения в базе данных.

  • deferrable – Необязательный параметр bool. Если установлен, то при выпуске DDL для этого ограничения выдавать DEFERRABLE или NOT DEFERRABLE.

  • initially – Необязательная строка. Если установлено, то при выпуске DDL для этого ограничения выдавать INITIALLY <значение>.

  • using – Необязательная строка. Если установлено, то при выпуске DDL для этого ограничения выдается USING <index_method>. По умолчанию установлено значение „gist“.

  • where – Необязательная конструкция выражения SQL или литеральная строка SQL. Если задано, то при выдаче DDL для этого ограничения выдается WHERE <предикат>. … предупреждение:: Аргумент ExcludeConstraint.where в ExcludeConstraint может быть передан как строковый аргумент Python, который будет рассматриваться как доверенный SQL-текст и отображаться как задано. НЕ ПЕРЕДАВАЙТЕ НЕДОВЕРЕННЫЙ ВВОД В ЭТОТ ПАРАМЕТР.

  • ops – Необязательный словарь. Используется для определения классов операторов для элементов; работает так же, как и параметр postgresql_ops, указанный в конструкции Index. … версия добавлена:: 1.3.21 … seealso:: Классы операторов - общее описание того, как задаются классы операторов PostgreSQL.

Например:

from sqlalchemy.dialects.postgresql import ExcludeConstraint, TSRANGE


class RoomBooking(Base):
    __tablename__ = "room_booking"

    room = Column(Integer(), primary_key=True)
    during = Column(TSRANGE())

    __table_args__ = (ExcludeConstraint(("room", "="), ("during", "&&")),)

Конструкции DML в PostgreSQL

Object Name Description

insert(table)

Создайте специфичную для PostgreSQL конструкцию варианта Insert.

Insert

Специфическая для PostgreSQL реализация INSERT.

function sqlalchemy.dialects.postgresql.insert(table)

Создайте специфичную для PostgreSQL конструкцию варианта Insert.

Функция sqlalchemy.dialects.postgresql.insert() создает sqlalchemy.dialects.postgresql.Insert. Этот класс основан на диалекте-ag

Конструкция Insert включает дополнительные методы Insert.on_conflict_do_update(), Insert.on_conflict_do_nothing().

class sqlalchemy.dialects.postgresql.Insert

Специфическая для PostgreSQL реализация INSERT.

Добавляет методы для специфических для PG синтаксисов, таких как ON CONFLICT.

Объект Insert создается с помощью функции sqlalchemy.dialects.postgresql.insert().

attribute sqlalchemy.dialects.postgresql.Insert.excluded

Предоставьте пространство имен excluded для оператора ON CONFLICT

Пункт ON CONFLICT в PG позволяет ссылаться на строку, которая будет вставлена, известную как excluded. Этот атрибут обеспечивает возможность ссылки на все столбцы в этой строке.

Совет

Атрибут Insert.excluded является экземпляром ColumnCollection, который предоставляет интерфейс, аналогичный интерфейсу коллекции Table.c, описанной в Доступ к таблицам и столбцам. В этой коллекции обычные имена доступны как атрибуты (например, stmt.excluded.some_column), но к специальным именам и именам методов словаря следует обращаться с помощью индексного доступа, например, stmt.excluded["column name"] или stmt.excluded["values"]. Дополнительные примеры см. в строке документации для ColumnCollection.

См.также

INSERT…ON CONFLICT (Upsert) - пример использования Insert.excluded

attribute sqlalchemy.dialects.postgresql.Insert.inherit_cache: Optional[bool] = False

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

По умолчанию атрибут имеет значение None, что указывает на то, что конструкция еще не приняла во внимание целесообразность ее участия в кэшировании; функционально это эквивалентно установке значения False, за исключением того, что при этом выдается предупреждение.

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

См.также

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

method sqlalchemy.dialects.postgresql.Insert.on_conflict_do_nothing(constraint=None, index_elements=None, index_where=None) Self

Указывает действие DO NOTHING для пункта ON CONFLICT.

Аргументы constraint и index_elements являются необязательными, но можно указать только один из них.

Параметры:
  • constraint – Имя уникального или исключающего ограничения для таблицы, или сам объект ограничения, если у него есть атрибут .name.

  • index_elements – Последовательность, состоящая из строковых имен столбцов, объектов Column или других объектов выражения столбцов, которые будут использоваться для вывода целевого индекса.

  • index_where – Дополнительный критерий WHERE, который может быть использован для вывода условного целевого индекса.

method sqlalchemy.dialects.postgresql.Insert.on_conflict_do_update(constraint=None, index_elements=None, index_where=None, set_=None, where=None) Self

Указывает действие DO UPDATE SET для условия ON CONFLICT.

Требуется либо аргумент constraint, либо index_elements, но можно указать только один из них.

Параметры:
  • constraint – Имя уникального или исключающего ограничения для таблицы, или сам объект ограничения, если у него есть атрибут .name.

  • index_elements – Последовательность, состоящая из строковых имен столбцов, объектов Column или других объектов выражения столбцов, которые будут использоваться для вывода целевого индекса.

  • index_where – Дополнительный критерий WHERE, который может быть использован для вывода условного целевого индекса.

  • set_ – Словарь или другой объект отображения, где ключами являются либо имена столбцов в целевой таблице, либо Column объекты или другие ORM-сопоставленные столбцы, совпадающие со столбцами целевой таблицы, а в качестве значений - выражения или литералы, определяющие действия SET, которые необходимо предпринять. … versionadded:: 1.4 Параметр Insert.on_conflict_do_update.set_ поддерживает Column объекты из целевой Table в качестве ключей. … предупреждение:: Этот словарь не учитывает значения UPDATE или функции генерации, заданные по умолчанию в Python, например, указанные с помощью Column.onupdate. Эти значения не будут использоваться для UPDATE в стиле ON CONFLICT, если они не указаны вручную в словаре Insert.on_conflict_do_update.set_.

  • where – Необязательный аргумент. Если присутствует, может быть литеральной строкой SQL или допустимым выражением для предложения WHERE, которое ограничивает строки, затрагиваемые DO UPDATE SET. Строки, не удовлетворяющие условию WHERE, не будут обновлены (эффективно DO NOTHING для этих строк).

psycopg2

Support for the PostgreSQL database via the psycopg2 driver.

DBAPI

Documentation and download information (if applicable) for psycopg2 is available at: https://pypi.org/project/psycopg2/

Connecting

Connect String:

postgresql+psycopg2://user:password@host:port/dbname[?key=value&key=value...]

psycopg2 Аргументы для подключения

В create_engine() можно передавать аргументы ключевых слов, специфичные для диалекта SQLAlchemy psycopg2:

Совет

Приведенные выше аргументы ключевых слов являются диалектными аргументами ключевых слов, что означает, что они передаются как явные аргументы ключевых слов в create_engine():

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

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

SSL-соединения

Модуль psycopg2 имеет аргумент соединения sslmode для управления его поведением относительно безопасных (SSL) соединений. По умолчанию используется значение sslmode=prefer; модуль будет пытаться установить SSL-соединение, а если это не удастся, он вернется к незашифрованному соединению. sslmode=require может быть использовано для обеспечения установления только безопасных соединений. Обратитесь к документации psycopg2 / libpq для получения дополнительной информации о доступных опциях.

Обратите внимание, что sslmode специфичен для psycopg2, поэтому он включен в URI соединения:

engine = sa.create_engine(
    "postgresql+psycopg2://scott:tiger@192.168.0.199:5432/test?sslmode=require"
)

Подключения к домену Unix

psycopg2 поддерживает подключение через соединения Unix-домена. Когда часть URL host опущена, SQLAlchemy передает psycopg2 часть None, что указывает на связь через Unix-домен, а не через TCP/IP:

create_engine("postgresql+psycopg2://user:password@/dbname")

По умолчанию используется файл сокета для подключения к сокету Unix-домена в каталоге /tmp, или в каталоге сокетов, который был указан при создании PostgreSQL. Это значение можно переопределить, передав psycopg2 имя пути, используя host в качестве дополнительного аргумента ключевое слово:

create_engine("postgresql+psycopg2://user:password@/dbname?host=/var/lib/postgresql")

См.также

PQconnectdbParams

Указание нескольких резервных хостов

psycopg2 поддерживает несколько точек подключения в строке подключения. Когда параметр host используется несколько раз в секции запроса URL, SQLAlchemy создаст единую строку из информации о хосте и порте, предоставленной для осуществления соединений. Токены могут состоять из host::port или просто host; в последнем случае порт по умолчанию выбирается libpq. В приведенном ниже примере указаны три соединения с хостом: HostA::PortA, HostB с портом по умолчанию и HostC::PortC:

create_engine(
    "postgresql+psycopg2://user:password@/dbname?host=HostA:PortA&host=HostB&host=HostC:PortC"
)

В качестве альтернативы также может быть использован формат строки запроса libpq, который определяет host и port как отдельные аргументы строки запроса со списками, разделенными запятыми - порт по умолчанию может быть выбран путем указания пустого значения в списке, разделенном запятыми:

create_engine(
    "postgresql+psycopg2://user:password@/dbname?host=HostA,HostB,HostC&port=PortA,,PortC"
)

При любом стиле URL соединения с каждым хостом пытаются установить на основе настраиваемой стратегии, которая может быть настроена с помощью параметра libpq target_session_attrs. В libpq этот параметр по умолчанию равен any, что означает, что соединение с каждым узлом будет пытаться до тех пор, пока соединение не будет успешным. Другие стратегии включают primary, prefer-standby и т.д. Полный список документирован PostgreSQL по адресу libpq connection strings.

Например, для обозначения двух хостов с помощью стратегии primary:

create_engine(
    "postgresql+psycopg2://user:password@/dbname?host=HostA:PortA&host=HostB&host=HostC:PortC&target_session_attrs=primary"
)

Изменено в версии 1.4.40: Исправлена спецификация портов в формате psycopg2 multiple host, ранее порты неправильно интерпретировались в этом контексте. Также теперь поддерживается формат libpq comma-separated.

Добавлено в версии 1.3.20: Поддержка нескольких хостов в строке подключения к PostgreSQL.

См.также

libpq connection strings - пожалуйста, обратитесь к этому разделу документации libpq для получения полной информации о поддержке нескольких хостов.

Пустые DSN-подключения / подключения переменных среды

psycopg2 DBAPI может подключаться к PostgreSQL, передавая пустой DSN клиентской библиотеке libpq, которая по умолчанию указывает на подключение к базе данных PostgreSQL на локальном хосте, открытой для «доверительных» соединений. Это поведение может быть дополнительно настроено с помощью определенного набора переменных окружения с префиксом PG_..., которые используются libpq, чтобы занять место любого или всех элементов строки соединения.

Для этой формы URL может быть передан без каких-либо элементов, кроме начальной схемы:

engine = create_engine('postgresql+psycopg2://')

В приведенной выше форме пустая строка «dsn» передается в функцию psycopg2.connect(), которая в свою очередь представляет собой пустой DSN, передаваемый в libpq.

Добавлено в версии 1.3.2: поддержка соединений без параметров с psycopg2.

См.также

Environment Variables - документация PostgreSQL о том, как использовать переменные среды PG_... для соединений.

Варианты выполнения за выписку/подключение

При использовании Connection.execution_options(), Executable.execution_options(), Query.execution_options() в дополнение к опциям, не характерным для DBAPI, соблюдаются следующие опции, специфичные для DBAPI:

  • isolation_level - Установить уровень изоляции транзакции на время жизни Connection (может быть установлен только для соединения, но не для оператора или запроса). См. Уровень изоляции транзакций Psycopg2.

  • stream_results - Включить или отключить использование курсоров psycopg2 на стороне сервера - эта функция использует «именованные» курсоры в сочетании со специальными методами обработки результатов, так что строки результатов не буферизируются полностью. По умолчанию установлено значение False, что означает, что курсоры буферизуются по умолчанию.

  • max_row_buffer - при использовании stream_results целочисленное значение, определяющее максимальное количество строк в буфере за один раз. Это значение интерпретируется параметром BufferedRowCursorResult, и если его опустить, буфер будет расти, чтобы в конечном итоге хранить 1000 строк за раз.

    Изменено в версии 1.4: Размер max_row_buffer теперь может быть больше 1000, и буфер вырастет до этого размера.

Помощники быстрого выполнения Psycopg2

Современные версии psycopg2 включают функцию, известную как Fast Execution Helpers , которая, как было показано в бенчмарках, улучшает производительность psycopg2 executemany(), в основном с операторами INSERT, как минимум на порядок

SQLAlchemy реализует собственную форму обработчика «вставки многих значений», который переписывает однострочный оператор INSERT для одновременного ввода многих значений в расширенном предложении VALUES; этот обработчик эквивалентен обработчику psycopg2 execute_values(); обзор этой функции и ее конфигурации находится в Поведение «Вставка многих значений» для операторов INSERT.

Добавлено в версии 2.0: Заменили помощник быстрого выполнения psycopg2 execute_values() на собственный механизм SQLAlchemy под названием insertmanyvalues.

Диалект psycopg2 сохраняет возможность использования специфической для psycopg2 функции execute_batch(), хотя не ожидается, что эта функция будет широко использоваться. Использование этого расширения может быть разрешено с помощью флага executemany_mode, который можно передать в create_engine():

engine = create_engine(
    "postgresql+psycopg2://scott:tiger@host/dbname",
    executemany_mode='values_plus_batch')

Возможные варианты для executemany_mode включают:

  • values_only - это значение по умолчанию. Родной обработчик SQLAlchemy insertmanyvalues используется для квалификации операторов INSERT, предполагая, что create_engine.use_insertmanyvalues оставлен в значении по умолчанию True. Этот обработчик переписывает простые операторы INSERT, чтобы включить в них несколько пунктов VALUES, так что в один оператор можно вставить множество наборов параметров.

  • 'values_plus_batch'- Родной обработчик SQLAlchemy insertmanyvalues используется для квалификации операторов INSERT, предполагая, что create_engine.use_insertmanyvalues оставлен на значении по умолчанию True. Затем, обработчик psycopg2 execute_batch() используется для квалификации операторов UPDATE и DELETE при выполнении с несколькими наборами параметров. При использовании этого режима атрибут CursorResult.rowcount не будет содержать значения для выполнения операторов UPDATE и DELETE в стиле executemany.

Изменено в версии 2.0: Удалены опции 'batch' и 'None' из psycopg2 executemany_mode. Управление пакетной обработкой для операторов INSERT теперь настраивается с помощью параметра create_engine.use_insertmanyvalues на уровне движка.

Термин «квалифицирующие операторы» означает, что выполняемый оператор является конструкцией Core insert(), update() или delete(), и не простой текстовой строкой SQL или построенной с использованием text(). Он также не может быть специальным оператором «расширения», таким как «ON CONFLICT» «upsert». При использовании ORM все операторы insert/update/delete, используемые процессом промывки ORM, являются квалификационными.

На «размер страницы» для стратегии psycopg2 «batch» можно повлиять с помощью параметра executemany_batch_page_size, который по умолчанию равен 100.

Для функции «insertmanyvalues» размер страницы можно контролировать с помощью параметра create_engine.insertmanyvalues_page_size, который по умолчанию равен 1000. Пример изменения обоих параметров приведен ниже:

engine = create_engine(
    "postgresql+psycopg2://scott:tiger@host/dbname",
    executemany_mode='values_plus_batch',
    insertmanyvalues_page_size=5000, executemany_batch_page_size=500)

См.также

Поведение «Вставка многих значений» для операторов INSERT - справочная информация по «insertmanyvalues»

Отправка нескольких параметров - Общая информация об использовании объекта Connection для выполнения операторов таким образом, чтобы использовать метод DBAPI .executemany().

Юникод с Psycopg2

Драйвер psycopg2 DBAPI прозрачно поддерживает данные Unicode.

Кодировкой символов клиента можно управлять для диалекта psycopg2 следующими способами:

  • Для PostgreSQL 9.1 и выше, параметр client_encoding может быть передан в URL базы данных; этот параметр потребляется основной клиентской библиотекой libpq PostgreSQL:

    engine = create_engine("postgresql+psycopg2://user:pass@host/dbname?client_encoding=utf8")

    Альтернативно, вышеуказанное значение client_encoding может быть передано с помощью create_engine.connect_args для программного установления с помощью libpq:

    engine = create_engine(
        "postgresql+psycopg2://user:pass@host/dbname",
        connect_args={'client_encoding': 'utf8'}
    )
  • Для всех версий PostgreSQL, psycopg2 поддерживает значение кодировки на стороне клиента, которое будет передаваться соединениям с базой данных при их первом установлении. Диалект SQLAlchemy psycopg2 поддерживает это с помощью параметра client_encoding, передаваемого в create_engine():

    engine = create_engine(
        "postgresql+psycopg2://user:pass@host/dbname",
        client_encoding="utf8"
    )

    Совет

    Приведенный выше параметр client_encoding по внешнему виду очень похож на использование параметра в словаре create_engine.connect_args; разница в том, что параметр потребляется psycopg2 и передается в соединение с базой данных с помощью SET client_encoding TO 'utf8'; в ранее упомянутом стиле параметр вместо этого передается через psycopg2 и потребляется библиотекой libpq.

  • Обычным способом настройки клиентской кодировки в базах данных PostgreSQL является настройка ее в файле postgresql.conf на стороне сервера; это рекомендуемый способ настройки кодировки для сервера, который последовательно использует одну кодировку во всех базах данных:

    # postgresql.conf file
    
    # client_encoding = sql_ascii # actually, defaults to database
                                 # encoding
    client_encoding = utf8

Транзакции

Диалект psycopg2 полностью поддерживает операции SAVEPOINT и двухфазную фиксацию.

Уровень изоляции транзакций Psycopg2

Как обсуждалось в Уровень изоляции транзакций, все диалекты PostgreSQL поддерживают установку уровня изоляции транзакций как через параметр isolation_level, передаваемый в create_engine(), так и через аргумент isolation_level, используемый в Connection.execution_options(). При использовании диалекта psycopg2 эти опции используют метод соединения psycopg2 set_isolation_level(), а не передают директиву PostgreSQL; это связано с тем, что установка уровня API psycopg2 всегда передается в начале каждой транзакции в любом случае.

Диалект psycopg2 поддерживает эти константы для уровня изоляции:

  • READ COMMITTED

  • READ UNCOMMITTED

  • REPEATABLE READ

  • SERIALIZABLE

  • AUTOCOMMIT

УВЕДОМЛЕНИЕ о лесозаготовках

Диалект psycopg2 будет регистрировать сообщения PostgreSQL NOTICE через логгер sqlalchemy.dialects.postgresql. Если этот логгер установлен на уровень logging.INFO, сообщения уведомлений будут регистрироваться:

import logging

logging.getLogger('sqlalchemy.dialects.postgresql').setLevel(logging.INFO)

Выше предполагалось, что протоколирование настроено извне. Если это не так, необходимо использовать конфигурацию типа logging.basicConfig():

import logging

logging.basicConfig()   # log messages to stdout
logging.getLogger('sqlalchemy.dialects.postgresql').setLevel(logging.INFO)

См.также

Logging HOWTO - на сайте python.org

Тип HSTORE

DBAPI psycopg2 включает в себя расширение для нативной обработки маршалинга типа HSTORE. Диалект SQLAlchemy psycopg2 включает это расширение по умолчанию, когда используется psycopg2 версии 2.4 или выше, и обнаруживается, что целевая база данных имеет тип HSTORE, установленный для использования. Другими словами, когда диалект устанавливает первое соединение, выполняется последовательность, подобная следующей:

  1. Запросите доступные идентификаторы HSTORE, используя psycopg2.extras.HstoreAdapter.get_oids(). Если эта функция возвращает список идентификаторов HSTORE, то мы определяем наличие расширения HSTORE. Эта функция пропускается, если установленная версия psycopg2 меньше версии 2.4.

  2. Если флаг use_native_hstore установлен по умолчанию True, и мы обнаружили, что доступны оиды HSTORE, то для всех соединений вызывается расширение psycopg2.extensions.register_hstore().

Расширение register_hstore() имеет эффект все словари Python принимаются в качестве параметров, независимо от типа целевого столбца в SQL. Словари преобразуются этим расширением в текстовое выражение HSTORE. Если такое поведение нежелательно, отключите использование расширения hstore, установив use_native_hstore в False следующим образом:

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

Тип HSTORE по-прежнему поддерживается, когда расширение psycopg2.extensions.register_hstore() не используется. Это просто означает, что согласование между словарями Python и форматом строк HSTORE, как на стороне параметров, так и на стороне результата, будет происходить в рамках собственной логики маршалинга SQLAlchemy, а не логики psycopg2, которая может быть более производительной.

psycopg

Support for the PostgreSQL database via the psycopg (a.k.a. psycopg 3) driver.

DBAPI

Documentation and download information (if applicable) for psycopg (a.k.a. psycopg 3) is available at: https://pypi.org/project/psycopg/

Connecting

Connect String:

postgresql+psycopg://user:password@host:port/dbname[?key=value&key=value...]

psycopg - это название пакета и модуля для третьей версии драйвера базы данных psycopg, ранее известного как psycopg2. Этот драйвер настолько отличается от своего предшественника psycopg2, что SQLAlchemy поддерживает его с помощью совершенно отдельного диалекта; ожидается, что поддержка psycopg2 будет сохраняться до тех пор, пока этот пакет будет функционировать для современных версий Python, а также останется диалектом по умолчанию для серии диалектов postgresql://.

Диалект SQLAlchemy psycopg предоставляет как синхронную, так и асинхронную реализацию под одним и тем же именем диалекта. Выбор подходящей версии зависит от того, как создается движок:

  • вызов create_engine() с postgresql+psycopg://... автоматически выберет версию синхронизации, например:

    from sqlalchemy import create_engine
    sync_engine = create_engine("postgresql+psycopg://scott:tiger@localhost/test")
  • вызов create_async_engine() с postgresql+psycopg://... автоматически выберет асинхронную версию, например:

    from sqlalchemy.ext.asyncio import create_async_engine
    asyncio_engine = create_async_engine("postgresql+psycopg://scott:tiger@localhost/test")

Версия диалекта asyncio также может быть указана явно с помощью суффикса psycopg_async, как:

from sqlalchemy.ext.asyncio import create_async_engine
asyncio_engine = create_async_engine("postgresql+psycopg_async://scott:tiger@localhost/test")

См.также

psycopg2 - Диалект SQLAlchemy psycopg разделяет большую часть своего поведения с диалектом psycopg2. Дополнительная документация доступна там.

pg8000

Support for the PostgreSQL database via the pg8000 driver.

DBAPI

Documentation and download information (if applicable) for pg8000 is available at: https://pypi.org/project/pg8000/

Connecting

Connect String:

postgresql+pg8000://user:password@host:port/dbname[?key=value&key=value...]

Изменено в версии 1.4: Диалект pg8000 был обновлен для версии 1.16.6 и выше, и снова является частью непрерывной интеграции SQLAlchemy с полной поддержкой функций.

Юникод

pg8000 будет кодировать / декодировать строковые значения между ним и сервером, используя параметр PostgreSQL client_encoding; по умолчанию это значение в файле postgresql.conf, который часто имеет значение по умолчанию SQL_ASCII. Обычно это значение может быть изменено на utf-8, как более полезное по умолчанию:

#client_encoding = sql_ascii # actually, defaults to database
                             # encoding
client_encoding = utf8

Значение client_encoding может быть отменено для сессии путем выполнения SQL:

SET CLIENT_ENCODING TO „utf8“;

SQLAlchemy будет выполнять этот SQL на всех новых соединениях на основе значения, переданного в create_engine() с помощью параметра client_encoding:

engine = create_engine(
    "postgresql+pg8000://user:pass@host/dbname", client_encoding='utf8')

SSL-соединения

pg8000 принимает объект Python SSLContext, который может быть указан с помощью словаря create_engine.connect_args:

import ssl
ssl_context = ssl.create_default_context()
engine = sa.create_engine(
    "postgresql+pg8000://scott:tiger@192.168.0.199/test",
    connect_args={"ssl_context": ssl_context},
)

Если сервер использует автоматически сгенерированный сертификат, который является самоподписным

import ssl
ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE
engine = sa.create_engine(
    "postgresql+pg8000://scott:tiger@192.168.0.199/test",
    connect_args={"ssl_context": ssl_context},
)

pg8000 Уровень изоляции транзакций

Диалект pg8000 предлагает те же настройки уровня изоляции, что и диалект psycopg2:

  • READ COMMITTED

  • READ UNCOMMITTED

  • REPEATABLE READ

  • SERIALIZABLE

  • AUTOCOMMIT

asyncpg

Support for the PostgreSQL database via the asyncpg driver.

DBAPI

Documentation and download information (if applicable) for asyncpg is available at: https://magicstack.github.io/asyncpg/

Connecting

Connect String:

postgresql+asyncpg://user:password@host:port/dbname[?key=value&key=value...]

Диалект asyncpg - это первый диалект asyncio в SQLAlchemy на языке Python.

Используя специальный посреднический слой asyncio, диалект asyncpg можно использовать в качестве бэкенда для пакета расширения SQLAlchemy asyncio.

Обычно этот диалект следует использовать только с функцией создания двигателя create_async_engine():

from sqlalchemy.ext.asyncio import create_async_engine
engine = create_async_engine("postgresql+asyncpg://user:pass@hostname/dbname")

Диалект также может быть запущен как «синхронный» диалект внутри функции create_engine(), которая будет передавать вызовы «await» в специальный цикл событий. Этот режим работы имеет ограниченное применение и предназначен только для специальных сценариев тестирования. Режим может быть включен путем добавления специфического для SQLAlchemy флага async_fallback к URL в сочетании с create_engine():

# for testing purposes only; do not use in production!
engine = create_engine("postgresql+asyncpg://user:pass@hostname/dbname?async_fallback=true")

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

Примечание

По умолчанию asyncpg не декодирует типы json и jsonb и возвращает их в виде строк. SQLAlchemy устанавливает декодер по умолчанию для типов json и jsonb, используя встроенную функцию python json.loads. Используемая реализация json может быть изменена путем установки атрибута json_deserializer при создании движка с помощью create_engine() или create_async_engine().

Кэш подготовленных заявлений

Диалект asyncpg SQLAlchemy использует asyncpg.connection.prepare() для всех операторов. Объекты подготовленных утверждений кэшируются после создания, что, по-видимому, позволяет повысить производительность вызова утверждений на 10% или более. Кэш работает на основе каждого соединения DBAPI, что означает, что основное хранилище подготовленных утверждений находится в пуле соединений DBAPI. Размер этого кэша по умолчанию составляет 100 операторов на DBAPI-соединение и может быть изменен с помощью аргумента DBAPI prepared_statement_cache_size (обратите внимание, что хотя этот аргумент реализован SQLAlchemy, он является частью части эмуляции DBAPI в диалекте asyncpg, поэтому обрабатывается как аргумент DBAPI, а не диалекта):

engine = create_async_engine("postgresql+asyncpg://user:pass@hostname/dbname?prepared_statement_cache_size=500")

Чтобы отключить кэш подготовленных операторов, используйте значение ноль:

engine = create_async_engine("postgresql+asyncpg://user:pass@hostname/dbname?prepared_statement_cache_size=0")

Добавлено в версии 1.4.0b2: Добавлено prepared_statement_cache_size для asyncpg.

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

Драйвер базы данных asyncpg обязательно использует кэши для OID типов PostgreSQL, которые становятся «устаревшими», когда пользовательские типы данных PostgreSQL, такие как объекты ENUM, изменяются с помощью операций DDL. Кроме того, сами подготовленные операторы, которые опционально кэшируются драйвером SQLAlchemy, как описано выше, также могут стать «несвежими», если в базу данных PostgreSQL был отправлен DDL, который изменяет таблицы или другие объекты, задействованные в конкретном подготовленном операторе.

Диалект SQLAlchemy asyncpg аннулирует эти кэши в рамках своего локального процесса, когда на локальном соединении появляются утверждения, представляющие собой DDL, но это можно контролировать только в рамках одного процесса Python / движка базы данных. Если изменения в DDL вносятся из других движков баз данных и/или процессов, работающее приложение может столкнуться с исключениями asyncpg InvalidCachedStatementError и/или InternalServerError("cache lookup failed for type <oid>"), если оно обращается к пулам соединений баз данных, которые работали с предыдущими структурами. Диалект SQLAlchemy asyncpg будет восстанавливаться после этих ошибок, когда драйвер вызывает эти исключения, очищая свои внутренние кэши, а также кэши драйвера asyncpg в ответ на них, но не может предотвратить их появление, если кэш подготовленного оператора или кэш типа asyncpg устарел, а также не может повторить запрос, поскольку транзакция PostgreSQL аннулируется при возникновении этих ошибок.

Название подготовленного заявления

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

from uuid import uuid4

engine = create_async_engine(
    "postgresql+asyncpg://user:pass@hostname/dbname",
    poolclass=NullPool,
    connect_args={
        'prepared_statement_name_func': lambda:  f'__asyncpg_{uuid4()}__',
    },
)

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

Чтобы предотвратить накопление бесполезных подготовленных операторов в вашем приложении, важно использовать класс пула NullPool и настроить PgBouncer на использование DISCARD при возврате соединений. Команда DISCARD используется для освобождения ресурсов, удерживаемых соединением db, включая подготовленные операторы. Без надлежащей настройки подготовленные операторы могут быстро накапливаться и вызывать проблемы с производительностью.

Отключение PostgreSQL JIT для улучшения обработки типа данных ENUM

Asyncpg имеет проблему issue при использовании типов данных PostgreSQL ENUM, когда при создании новых соединений с базой данных может быть выполнен дорогостоящий запрос для получения метаданных о пользовательских типах, что, как было показано, негативно влияет на производительность. Чтобы уменьшить эту проблему, параметр PostgreSQL «jit» может быть отключен на клиенте с помощью этого параметра, передаваемого в create_async_engine():

engine = create_async_engine(
    "postgresql+asyncpg://user:password@localhost/tmp",
    connect_args={"server_settings": {"jit": "off"}},
)

psycopg2cffi

Support for the PostgreSQL database via the psycopg2cffi driver.

DBAPI

Documentation and download information (if applicable) for psycopg2cffi is available at: https://pypi.org/project/psycopg2cffi/

Connecting

Connect String:

postgresql+psycopg2cffi://user:password@host:port/dbname[?key=value&key=value...]

psycopg2cffi является адаптацией psycopg2, используя CFFI для слоя C. Это делает его пригодным для использования, например, в PyPy. Документация соответствует psycopg2.

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