PostgreSQL¶
Support for the PostgreSQL database.
The following table summarizes current support levels for database release versions.
Support type |
Versions |
---|---|
9.6, 10, 11, 12, 13, 14 |
|
9.6+ |
|
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
Полнотекстовый поиск¶
Система полнотекстового поиска PostgreSQL доступна благодаря использованию пространства имен func
в сочетании с использованием пользовательских операторов с помощью метода Operators.bool_op()
. Для простых случаев с некоторой степенью кросс-бэкенд совместимости можно также использовать оператор Operators.match()
.
Простое сопоставление обычного текста с помощью match()
¶
Оператор Operators.match()
обеспечивает кросс-совместимое простое сопоставление текста. Для бэкенда PostgreSQL жестко закодировано создание выражения с использованием оператора @@
в сочетании с функцией plainto_tsquery()
PostgreSQL.
В диалекте PostgreSQL выражение, подобное следующему:
select(sometable.c.text.match("search string"))
будет передаваться в базу данных:
SELECT text @@ plainto_tsquery('search string') FROM table
Выше, при передаче простой строки в Operators.match()
автоматически будет использоваться plainto_tsquery()
для указания типа tsquery. Это устанавливает базовую перекрестную совместимость базы данных Operators.match()
с другими бэкендами.
Изменено в версии 2.0: Функция генерации tsquery по умолчанию, используемая диалектом PostgreSQL с Operators.match()
, - это plainto_tsquery()
.
Чтобы отобразить именно то, что было отображено в 1.4, используйте следующую форму:
from sqlalchemy import func
select(
sometable.c.text.bool_op("@@")(func.to_tsquery("search string"))
)
Который будет излучать:
SELECT text @@ to_tsquery('search string') FROM table
Прямое использование полнотекстовых функций и операторов PostgreSQL¶
Операции поиска текста, выходящие за рамки простого использования Operators.match()
, могут использовать пространство имен func
для генерации полнотекстовых функций PostgreSQL, в сочетании с Operators.bool_op()
для генерации любого булевого оператора.
Например, запрос:
select(
func.to_tsquery('cat').bool_op("@>")(func.to_tsquery('cat & rat'))
)
будет генерировать:
SELECT to_tsquery('cat') @> to_tsquery('cat & rat')
Тип TSVECTOR
может предусматривать явный CAST:
from sqlalchemy.dialects.postgresql import TSVECTOR
from sqlalchemy import select, cast
select(cast("some text", TSVECTOR))
выдает утверждение, эквивалентное:
SELECT CAST('some text' AS TSVECTOR) AS anon_1
Пространство имен func
дополнено диалектом PostgreSQL для установки правильных типов аргументов и возврата для большинства функций полнотекстового поиска. Эти функции автоматически используются пространством имен sqlalchemy.sql.expression.func
при условии, что пакет sqlalchemy.dialects.postgresql
был импортирован или create_engine()
был вызван с помощью диалекта postgresql
. Эти функции документированы по адресу:
Указание «regconfig» с помощью match()
или пользовательских операторов¶
Функция PostgreSQL plainto_tsquery()
принимает дополнительный аргумент «regconfig», который используется для указания PostgreSQL использовать определенный предварительно вычисленный индекс GIN или GiST для выполнения поиска. При использовании функции Operators.match()
этот дополнительный параметр может быть указан с помощью параметра postgresql_regconfig
, например:
select(mytable.c.id).where(
mytable.c.title.match('somestring', postgresql_regconfig='english')
)
Который будет излучать:
SELECT mytable.id FROM mytable
WHERE mytable.title @@ plainto_tsquery('english', 'somestring')
При использовании других функций поиска PostgreSQL с func
, параметр «regconfig» может быть передан непосредственно в качестве начального аргумента:
select(mytable.c.id).where(
func.to_tsvector("english", mytable.c.title).bool_op("@@")(
func.to_tsquery("english", "somestring")
)
)
выдает утверждение, эквивалентное:
SELECT mytable.id FROM mytable
WHERE to_tsvector('english', mytable.title) @@
to_tsquery('english', 'somestring')
Рекомендуется использовать инструмент EXPLAIN ANALYZE...
из PostgreSQL, чтобы убедиться, что вы создаете запросы в SQLAlchemy, которые в полной мере используют преимущества любых индексов, которые вы создали для полнотекстового поиска.
См.также
Full Text Search - в документации по PostgreSQL
ТОЛЬКО …¶
Диалект поддерживает ключевое слово 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 |
---|---|
- class sqlalchemy.dialects.postgresql.base.PGInspector¶
-
**Классный сиг
класс
sqlalchemy.dialects.postgresql.base.PGInspector
(sqlalchemy.engine.reflection.Inspector
)-
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.
-
method
Параметры таблиц 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
- тип данных ARRAYarray
- литерал массиваarray_agg()
- SQL-функция ARRAY_AGGaggregate_order_by
- помощник для синтаксиса агрегатной функции ORDER BY в PG.
Типы JSON¶
Диалект PostgreSQL поддерживает оба типа данных JSON и JSONB, включая встроенную поддержку psycopg2 и поддержку всех специальных операторов PostgreSQL:
Тип HSTORE¶
Поддерживается тип PostgreSQL HSTORE, а также литералы hstore:
Типы ENUM¶
В PostgreSQL есть независимо создаваемая структура TYPE, которая используется для реализации перечислимого типа. Этот подход вводит сиг
ENUM
- DDL и поддержка типизации для ENUM.PGInspector.get_enums()
- получение списка текущих типов ENUMENUM.create()
,ENUM.drop()
- отдельные команды CREATE и DROP для ENUM.
Использование 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 |
---|---|
Представляет собой диапазон PostgreSQL. |
- class sqlalchemy.dialects.postgresql.Range¶
Представляет собой диапазон PostgreSQL.
Например:
r = Range(10, 50, bounds="()")
Стиль вызова похож на стиль вызова psycopg и psycopg2, отчасти для того, чтобы облегчить миграцию с предыдущих версий SQLAlchemy, которые использовали эти объекты напрямую.
- Параметры:
lower – Значение нижней границы, или Нет
upper – Верхнее граничное значение, или Нет
bounds – только ключевое слово, необязательное строковое значение, которое является одним из
"()"
,"[)"
,"(]"
,"[]"
. По умолчанию это значение равно"[)"
.empty – только ключевое слово, необязательный bool, указывающий, что это «пустой» диапазон
Добавлено в версии 2.0.
Members
__eq__(), adjacent_to(), contained_by(), contains(), difference(), intersection(), is_empty, isempty, lower, lower_inc, lower_inf, not_extend_left_of(), not_extend_right_of(), overlaps(), strictly_left_of(), strictly_right_of(), union(), upper, upper_inc, upper_inf
**Классный сиг
класс
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 |
---|---|
база для типов PostgreSQL MULTIRANGE |
|
База для типов RANGE в PostgreSQL. |
|
Тип PostgreSQL ARRAY. |
|
Укажите тип PostgreSQL CITEXT. |
|
Представляет тип PostgreSQL DATEMULTIRANGE. |
|
Представляет тип PostgreSQL DATERANGE. |
|
Представляет тип DOMAIN PostgreSQL. |
|
Тип PostgreSQL ENUM. |
|
Представляет собой тип PostgreSQL HSTORE. |
|
Представляет тип PostgreSQL INT4MULTIRANGE. |
|
Представляет тип PostgreSQL INT4RANGE. |
|
Представляет тип PostgreSQL INT8MULTIRANGE. |
|
Представляет тип PostgreSQL INT8RANGE. |
|
PostgreSQL Тип INTERVAL. |
|
Представляет тип PostgreSQL JSON. |
|
Представляет тип PostgreSQL JSONB. |
|
JSON Тип пути. |
|
Укажите тип PostgreSQL MONEY. |
|
Представляет тип PostgreSQL NUMMULTIRANGE. |
|
Представляет тип PostgreSQL NUMRANGE. |
|
Укажите тип OID PostgreSQL. |
|
Укажите тип PostgreSQL REGCLASS. |
|
Укажите тип PostgreSQL REGCONFIG. |
|
PostgreSQL Тип времени. |
|
Укажите тип PostgreSQL TIMESTAMP. |
|
Представляет тип PostgreSQL TSRANGE. |
|
Укажите тип PostgreSQL TSQUERY. |
|
Представляет тип PostgreSQL TSRANGE. |
|
Представляет тип PostgreSQL TSTZRANGE. |
|
Представляет тип PostgreSQL TSTZRANGE. |
|
Тип |
- class sqlalchemy.dialects.postgresql.AbstractRange¶
База для типов RANGE в PostgreSQL.
См.также
Members
adjacent_to(), contained_by(), contains(), difference(), intersection(), not_extend_left_of(), not_extend_right_of(), overlaps(), strictly_left_of(), strictly_right_of(), union()
**Классный сиг
класс
sqlalchemy.dialects.postgresql.AbstractRange
(sqlalchemy.types.TypeEngine
)- 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] ¶ Выражение диапазона. Возвращает объединение двух диапазонов. Вызывает исключение, если полученный диапазон не является смежным.
-
method
- 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()
, создавать события, которые будут обнаружены блоком работы. Обратите внимание, что изменения элементов внутри массива, включая подмассивы, которые изменяются на месте, не обнаруживаются.В качестве альтернативы можно назначить
Members
**Классный сиг
класс
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
-
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¶
**Классный сиг
класс
sqlalchemy.dialects.postgresql.BIT
(sqlalchemy.types.TypeEngine
)
- class sqlalchemy.dialects.postgresql.BYTEA¶
Members
**Классный сиг
класс
sqlalchemy.dialects.postgresql.BYTEA
(sqlalchemy.types.LargeBinary
)-
method
sqlalchemy.dialects.postgresql.BYTEA.
__init__(length: Optional[int] = None)¶ наследуется от
sqlalchemy.types.LargeBinary.__init__
методаLargeBinary
Создайте тип LargeBinary.
- Параметры:
length – опционально, длина столбца для использования в DDL-запросах, для тех бинарных типов, которые принимают длину, например, тип MySQL BLOB.
-
method
- class sqlalchemy.dialects.postgresql.CIDR¶
**Классный сиг
класс
sqlalchemy.dialects.postgresql.CIDR
(sqlalchemy.types.TypeEngine
)
- class sqlalchemy.dialects.postgresql.CITEXT¶
Укажите тип PostgreSQL CITEXT.
Добавлено в версии 2.0.7.
Members
**Классный сиг
класс
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
, которые предполагают хранение неасксичных данных. Эти типы данных гарантируют, что в базе данных используются правильные типы.
-
method
- 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.
Members
**Классный сиг
класс
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, чтобы проверить, существует ли тип на самом деле, прежде чем отбросить его.
-
method
- 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. Чтобы создать базу данных agasdecimal – тот же флаг, что и у
Numeric
, но по умолчанию имеет значениеFalse
. Обратите внимание, что установка этого флага в значениеTrue
приводит к преобразованию с плавающей точкой.decimal_return_scale – Масштаб по умолчанию, используемый при преобразовании значений с плавающей точкой в десятичные числа Python. Значения с плавающей точкой обычно намного длиннее из-за неточности десятичных дробей, а большинство типов баз данных с плавающей точкой не имеют понятия «масштаб», поэтому по умолчанию тип float ищет первые десять десятичных знаков при преобразовании. Указание этого значения отменяет эту длину. Обратите внимание, что типы MySQL float, которые включают «масштаб», будут использовать «масштаб» по умолчанию для decimal_return_scale, если не указано иное.
-
method
- class sqlalchemy.dialects.postgresql.ENUM¶
Тип PostgreSQL ENUM.
Это подкласс
Enum
, который включает поддержку PGCREATE 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)
Members
**Классный сиг
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, чтобы проверить, существует ли тип на самом деле, прежде чем отбросить его.
-
method
- 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
- рендеринг функции PostgreSQLhstore()
.Members
array(), contained_by(), contains(), defined(), delete(), has_all(), has_any(), has_key(), keys(), matrix(), slice(), vals(), __init__(), bind_processor(), comparator_factory, hashable, result_processor()
**Классный сиг
class
sqlalchemy.dialects.postgresql.HSTORE
(sqlalchemy.types.Indexable
,sqlalchemy.types.Concatenable
,sqlalchemy.types.TypeEngine
)- 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
-
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¶
**Классный сиг
класс
sqlalchemy.dialects.postgresql.INET
(sqlalchemy.types.TypeEngine
)
- class sqlalchemy.dialects.postgresql.INTERVAL¶
PostgreSQL Тип INTERVAL.
Members
**Классный сиг
класс
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
-
method
- class sqlalchemy.dialects.postgresql.JSON¶
Представляет тип PostgreSQL JSON.
JSON
используется автоматически, когда базовый тип данныхJSON
используется против бэкенда PostgreSQL, однако базовый тип данныхJSON
не предоставляет Python-доступ для специфических для PostgreSQL методов сравнения, таких какComparator.astext()
; кроме того, для использования PostgreSQLJSONB
необходимо явно использовать тип данных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
.Members
**Классный сиг
класс
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)
См.также
-
attribute
-
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.См.также
Members
contained_by(), contains(), delete_path(), has_all(), has_any(), has_key(), path_exists(), path_match(), comparator_factory
**Классный сиг
класс
sqlalchemy.dialects.postgresql.JSONB
(sqlalchemy.dialects.postgresql.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.
-
method
-
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¶
**Классный сиг
класс
sqlalchemy.dialects.postgresql.MACADDR
(sqlalchemy.types.TypeEngine
)
- class sqlalchemy.dialects.postgresql.MACADDR8¶
**Классный сиг
класс
sqlalchemy.dialects.postgresql.MACADDR8
(sqlalchemy.types.TypeEngine
)
- 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.
**Классный сиг
класс
sqlalchemy.dialects.postgresql.MONEY
(sqlalchemy.types.TypeEngine
)
- class sqlalchemy.dialects.postgresql.OID¶
Укажите тип OID PostgreSQL.
**Классный сиг
класс
sqlalchemy.dialects.postgresql.OID
(sqlalchemy.types.TypeEngine
)
- 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. Чтобы создать базу данных agasdecimal – тот же флаг, что и у
Numeric
, но по умолчанию имеет значениеFalse
. Обратите внимание, что установка этого флага в значениеTrue
приводит к преобразованию с плавающей точкой.decimal_return_scale – Масштаб по умолчанию, используемый при преобразовании значений с плавающей точкой в десятичные числа Python. Значения с плавающей точкой обычно намного длиннее из-за неточности десятичных дробей, а большинство типов баз данных с плавающей точкой не имеют понятия «масштаб», поэтому по умолчанию тип float ищет первые десять десятичных знаков при преобразовании. Указание этого значения отменяет эту длину. Обратите внимание, что типы MySQL float, которые включают «масштаб», будут использовать «масштаб» по умолчанию для decimal_return_scale, если не указано иное.
-
method
- class sqlalchemy.dialects.postgresql.REGCONFIG¶
Укажите тип PostgreSQL REGCONFIG.
Добавлено в версии 2.0.0rc1.
**Классный сиг
класс
sqlalchemy.dialects.postgresql.REGCONFIG
(sqlalchemy.types.TypeEngine
)
- class sqlalchemy.dialects.postgresql.REGCLASS¶
Укажите тип PostgreSQL REGCLASS.
Добавлено в версии 1.2.7.
**Классный сиг
класс
sqlalchemy.dialects.postgresql.REGCLASS
(sqlalchemy.types.TypeEngine
)
- class sqlalchemy.dialects.postgresql.TIMESTAMP¶
Укажите тип PostgreSQL TIMESTAMP.
Members
**Классный сиг
класс
sqlalchemy.dialects.postgresql.TIMESTAMP
(sqlalchemy.types.TIMESTAMP
)-
method
sqlalchemy.dialects.postgresql.TIMESTAMP.
__init__(timezone: bool = False, precision: Optional[int] = None) None ¶ Постройте TIMESTAMP.
- Параметры:
timezone – булево значение, если присутствует часовой пояс, по умолчанию False
precision – необязательное целочисленное значение точности .. versionadded:: 1.4
-
method
- class sqlalchemy.dialects.postgresql.TIME¶
PostgreSQL Тип времени.
Members
**Классный сиг
класс
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
-
method
- class sqlalchemy.dialects.postgresql.TSQUERY¶
Укажите тип PostgreSQL TSQUERY.
Добавлено в версии 2.0.0rc1.
**Классный сиг
класс
sqlalchemy.dialects.postgresql.TSQUERY
(sqlalchemy.types.TypeEngine
)
- class sqlalchemy.dialects.postgresql.TSVECTOR¶
Тип
TSVECTOR
реализует тип текстового поиска PostgreSQL TSVECTOR.Его можно использовать для выполнения полнотекстовых запросов к документам на естественном языке.
См.также
**Классный сиг
класс
sqlalchemy.dialects.postgresql.TSVECTOR
(sqlalchemy.types.TypeEngine
)
- class sqlalchemy.dialects.postgresql.UUID
Представляет тип SQL UUID.
Это SQL-нативная форма базы данных
Uuid
agТип данных
UUID
работает только с базами данных, которые имеют тип данных SQL с именемUUID
. Он не будет работать для бэкендов, которые не имеют такого типа с точным названием, включая SQL Server. Для бэкенд-агДобавлено в версии 2.0.
См.также
**Классный сиг
класс
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
.
-
method
- 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 |
---|---|
Представляет собой агрегатный порядок PostgreSQL по выражению. |
|
All(other, arrexpr[, operator]) |
Синоним метода ARRAY-level |
Any(other, arrexpr[, operator]) |
Синоним метода ARRAY-level |
Литерал PostgreSQL ARRAY. |
|
array_agg(*arg, **kw) |
Специфическая для PostgreSQL форма |
Создайте значение hstore в выражении SQL с помощью функции PostgreSQL |
|
SQL-функция PostgreSQL |
|
SQL-функция PostgreSQL |
|
SQL-функция PostgreSQL |
|
SQL-функция PostgreSQL |
|
SQL-функция PostgreSQL |
|
SQL-функция PostgreSQL |
- 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
См.также
- 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: добавлена поддержка литералов многомерных массивов
См.также
**Классный сиг
класс
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
- тип данных PostgreSQLHSTORE
.Members
**Классный сиг
класс
sqlalchemy.dialects.postgresql.hstore
(sqlalchemy.sql.functions.GenericFunction
)-
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
-
attribute
- 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 |
---|---|
Ограничение EXCLUDE на уровне таблицы. |
- class sqlalchemy.dialects.postgresql.ExcludeConstraint¶
Ограничение EXCLUDE на уровне таблицы.
Определяет ограничение EXCLUDE, как описано в PostgreSQL documentation.
Members
**Классный сиг
класс
sqlalchemy.dialects.postgresql.ExcludeConstraint
(sqlalchemy.schema.ColumnCollectionConstraint
)-
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 aColumn
object is not available, while ensuring that any necessary quoting rules take effect, an ad-hocColumn
orcolumn()
object should be used. Thecolumn
may also be a string SQL expression when passed asliteral_column()
ortext()
).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.
-
method
Например:
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 конструкцию варианта |
Специфическая для 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()
.**Классный сиг
класс
sqlalchemy.dialects.postgresql.Insert
(sqlalchemy.sql.expression.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
для этих строк).
См.также
-
attribute
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:
isolation_level
: Эта опция, доступная для всех диалектов PostgreSQL, включает уровень изоляцииAUTOCOMMIT
при использовании диалекта psycopg2. Эта опция устанавливает уровень изоляции по умолчанию для соединения, который устанавливается непосредственно при подключении к базе данных до того, как соединение будет объединено в пул. Эта опция обычно заменяется более современной опцией выполненияConnection.execution_options.isolation_level
, подробно описанной в Установка уровней изоляции транзакций, включая DBAPI Autocommit.client_encoding
: устанавливает кодировку клиента в libpq-agСм.также
executemany_mode
,executemany_batch_page_size
,executemany_values_page_size
: Позволяет использовать расширения psycopg2 для оптимизации запросов в стиле «executemany». Подробности см. в разделе со ссылками ниже.
Совет
Приведенные выше аргументы ключевых слов являются диалектными аргументами ключевых слов, что означает, что они передаются как явные аргументы ключевых слов в 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")
См.также
Указание нескольких резервных хостов¶
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
. Затем, обработчик psycopg2execute_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, установленный для использования. Другими словами, когда диалект устанавливает первое соединение, выполняется последовательность, подобная следующей:
Запросите доступные идентификаторы HSTORE, используя
psycopg2.extras.HstoreAdapter.get_oids()
. Если эта функция возвращает список идентификаторов HSTORE, то мы определяем наличие расширенияHSTORE
. Эта функция пропускается, если установленная версия psycopg2 меньше версии 2.4.Если флаг
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
.