PostgreSQL的¶


支持 PostgreSQL 数据库。


下表总结了数据库发行版的当前支持级别。


支持的 PostgreSQL 版本


支撑类型


版本


支持的版本

9.6+


尽力而为

9+


DBAPI 支持


以下 dialect/DBAPI 选项可用。有关连接信息,请参阅各个 DBAPI 部分。


序列/SERIAL/IDENTITY


PostgreSQL 支持序列,SQLAlchemy 使用这些序列作为为基于整数的主键列创建新主键值的默认方法。在创建表时,SQLAlchemy 将为基于整数的主键列发出 SERIAL 数据类型,这将生成与该列对应的 sequence 和 server side default。


要指定要用于主键生成的特定命名序列,请使用 Sequence() 构造:

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


当 SQLAlchemy 发出单个 INSERT 语句时,为了实现“最后一个插入标识符”可用的约定,将向 INSERT 语句添加一个 RETURNING 子句,该子句指定在语句完成后应返回主键列。仅当使用 PostgreSQL 8.2 或更高版本时,才会使用 RETURNING 功能。作为回退方法,序列(无论是通过 SERIAL 显式指定还是隐式指定)都是 独立执行,返回的值将在 随后的插入。请注意,当 insert() 结构使用 “executemany” 语义执行,则 “last inserted identifier” 功能不适用;在这种情况下,不会发出 RETURNING 子句,也不会预先执行序列。


PostgreSQL 10 及更高版本的 IDENTITY 列


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),
)


上述 Table 对象的 CREATE TABLE 将为:

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


在 1.4 版本发生变更: Column 中添加了 Identity 构造,以指定自动递增列的选项。


注意


以前版本的 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 版后已移除: 已弃用 dialect 级别 server_side_cursors 标志 ,并将在未来发行版中删除。 请使用 Connection.stream_results 无缓冲游标支持的执行选项。


事务隔离级别


大多数 SQLAlchemy 方言都支持在 create_engine() 级别和 Connection 级别使用 create_engine.isolation_level 参数设置事务隔离级别 级别通过 Connection.execution_options.isolation_level 参数。


对于 PostgreSQL 方言,此功能可以通过使用 DBAPI 特定的功能来工作,例如 psycopg2 的隔离级别标志,它将嵌入与 “BEGIN” 语句内联的隔离级别设置,或者对于没有直接支持的 DBAPI,通过在 DBAPI 发出的 “BEGIN” 语句之前发出 SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL <level> 。对于特殊的 AUTOCOMMIT 隔离级别,使用特定于 DBAPI 的技术,通常是 .autocommit 标志。


要使用 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


隔离级别配置还有更多选项,例如链接到主引擎的“子引擎”对象,每个选项都适用 不同的隔离级别设置。 请参阅讨论 设置事务隔离级别,包括 DBAPI 自动提交作为背景。


大多数 PostgreSQL 方言上 isolation_level 的有效值包括:


  • 读取已提交


  • 读取 UNCOMMITTED


  • 可重复读取


  • 序列 化


  • 自动提交


设置 READ ONLY / DEFERRABLE


大多数 PostgreSQL 方言都支持设置事务的 “READ ONLY” 和 “DEFERRABLE” 特征,这是对隔离级别设置的补充。这两个属性可以与隔离级别一起建立,也可以独立于隔离级别建立,方法是将 postgresql_readonlypostgresql_deferrable 标志 Connection.execution_options() 。下面的示例说明了在设置 “READ ONLY” 和 “DEFERRABLE” 的同时传递 “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)仅支持具有 SERIALIZABLE 隔离的 “readonly”。


在 1.4 版本加入: 添加了对 postgresql_readonly 的支持 和 postgresql_deferrable 执行选项。


连接池的临时 Table / Resource 重置


SQLAlchemy Engine 对象使用的 QueuePool 连接池实现包括 reset on return 行为,该行为将在连接返回到池时调用 DBAPI .rollback() 方法。 虽然此回滚将清除上一个 transaction,它不会涵盖更广泛的会话级状态,包括 临时表以及其他服务器状态,例如准备好的语句 句柄和语句缓存。 PostgreSQL 数据库包括各种 of 命令,包括 DISCARD、RESET、DEALLOCATEUNLISTEN。


要安装这些命令中的一个或多个作为执行 reset-on-return 的方法,可以使用 PoolEvents.reset() 事件钩子,如下例所示。该实现将结束正在进行的事务,并使用 CLOSE、RESETDISCARD 命令丢弃临时表;请参阅 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() 事件添加了额外的状态参数,并额外确保为所有 “reset” 事件调用该事件,以便它适合作为自定义 “reset” 处理程序的位置。以前使用 PoolEvents.checkin() 处理程序的方案也仍然可用。


另请参阅


Return 时重置 - 在 Connection Pooling 文档中


在 Connect 上设置备用搜索路径


PostgreSQL search_path 变量引用架构名称列表 ,当特定表或其他 object 在 SQL 语句中引用。 如下一节所述 Remote-Schema Table Introspection 和 PostgreSQL search_path,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


使用 .autocommit DBAPI 属性使配方复杂化的原因是,当调用 SET SESSION search_path 指令时,它将在任何事务的范围之外调用,因此当 DBAPI 连接回滚时,它不会被恢复。


Remote-Schema 表自省和 PostgreSQL search_path


部分 最佳实践总结


search_path 变量设置为其默认值 public,而不使用任何其他架构名称。确保用于连接的用户名不是 match remote schemas,或$user确保从 search_path。对于其他架构名称,请在 Table definitions 中显式命名这些名称。或者, postgresql_ignore_search_path选项将导致所有 Table 对象具有 Table.schema 属性设置。


PostgreSQL 方言可以反映任何架构中的表,如 反映来自其他架构的表


在所有情况下,SQLAlchemy 在反射 table 时做的第一件事是确定当前数据库连接的默认模式。它使用 PostgreSQL current_schema() 来执行此作 函数,如下所示,使用 PostgreSQL 客户端会话(即使用 psql 工具):

test=> select current_schema();
current_schema
----------------
public
(1 row)


在上面我们看到,在 PostgreSQL 的普通安装中,默认模式名称是名称 public


但是,如果您的数据库用户名与架构的名称匹配,则 PostgreSQL 的默认设置是使用该名称作为默认架构。下面,我们使用用户名 scott.当我们创建一个名为 scott 的 schema 时,它会 隐式更改默认架构

test=> select current_schema();
current_schema
----------------
public
(1 row)

test=> create schema scott;
CREATE SCHEMA
test=> select current_schema();
current_schema
----------------
scott
(1 row)


current_schema() 的行为源自 PostgreSQL 搜索路径 变量 search_path,在现代 PostgreSQL 版本中默认为:

test=> show search_path;
search_path
-----------------
"$user", public
(1 row)


在上面,“$user” 变量将注入当前用户名作为默认架构(如果存在)。否则,使用 public


Table 对象被镜像时,如果它存在于 current_schema() 函数指示的架构中,则分配的架构名称 到 Table 的 “.schema” 属性中是 Python 的 “None” 值。否则,将为 “.schema” 属性分配该架构的字符串名称。


对于这些 Table objects 引用 VIA 外键约束,则必须决定如何 .schema 在这些远程表中表示,如果该远程模式名称也是当前 search_path 的成员。


默认情况下,PostgreSQL 方言模仿 PostgreSQL 自己的 pg_get_constraintdef() 内置过程鼓励的行为。此函数返回特定外键约束的示例定义,当该名称也在 PostgreSQL 架构搜索路径中时,从该定义中省略引用的架构名称。下面的交互说明了这种行为:

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)


上面,我们创建了一个称为远程架构成员的表 但是,test_schema,当我们向 PG search_path 添加 test_schema,然后要求 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() 的返回值 以确定远程 Schema 名称。 也就是说,如果我们的 search_path 设置为包括 test_schema,我们调用了一个 Table Reflection 过程,如下所示:

>>> 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 收集 引用的表命名时没有架构:

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


要更改反射的行为,以便无论 search_path 设置如何,都保留引用的架构,请使用 postgresql_ignore_search_path选项,该选项可以指定为 TableMetaData.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.refer 存储为 schema-qualified:

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


另请参阅


Schema 限定的反射与默认 Schema 的交互 - 从后端不可知的角度讨论问题


架构搜索路径 - 在 PostgreSQL 网站上。


插入/更新...返回


该方言支持 PG 8.2 的 INSERT..返回更新..RETURNING删除。。RETURNING 语法。插入。。默认情况下,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())


插入。。。冲突时 (Upsert)


从版本 9.5 开始,PostgreSQL 允许通过 INSERT 语句的 ON CONFLICT 子句将行“更新插入”(更新或插入)到表中。仅当候选行不违反任何唯一约束时,才会插入该行。在唯一约束冲突的情况下,可能会发生辅助作,该作可以是“DO UPDATE”,表示应更新目标行中的数据,也可以是“DO NOTHING”,表示以静默方式跳过此行。


使用现有的唯一约束和索引确定冲突。可以使用 DDL 中所述的名称来标识这些约束,也可以通过声明组成索引的列和条件来推断它们。


SQLAlchemy 通过特定于 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)
INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s) ON CONFLICT (id) DO NOTHING
>>> do_update_stmt = insert_stmt.on_conflict_do_update( ... constraint="pk_my_table", set_=dict(data="updated value") ... ) >>> print(do_update_stmt)
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


另请参阅


插入。。冲突时 - 在 PostgreSQL 文档中。


指定目标


这两种方法都使用命名约束或 by column 推理提供冲突的 “目标”:


  • 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)
    
    INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s) ON CONFLICT (id) DO UPDATE SET data = %(param_1)s
    >>> do_update_stmt = insert_stmt.on_conflict_do_update( ... index_elements=[my_table.c.id], set_=dict(data="updated value") ... ) >>> print(do_update_stmt)
    INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s) ON CONFLICT (id) DO UPDATE SET data = %(param_1)s

  • 当 using Insert.on_conflict_do_update.index_elements 用于推断索引时,还可以通过指定 use the Insert.on_conflict_do_update.index_where parameter 来推断部分索引:

    >>> 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)
    
    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 约束或 INDEX 的名称:

    >>> do_update_stmt = insert_stmt.on_conflict_do_update(
    ...     constraint="my_table_idx_1", set_=dict(data="updated value")
    ... )
    >>> print(do_update_stmt)
    
    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
    >>> do_update_stmt = insert_stmt.on_conflict_do_update( ... constraint="my_table_pk", set_=dict(data="updated value") ... ) >>> print(do_update_stmt)
    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

  • Insert.on_conflict_do_update.constraint 参数还可以引用表示约束的 SQLAlchemy 结构,例如 UniqueConstraintPrimaryKeyConstraintIndexExcludeConstraint 的 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)
    
    INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s) ON CONFLICT (id) DO UPDATE SET data = %(param_1)s


SET 子句


关于冲突...DO UPDATE 用于执行已 existing row, 使用新值和值的任意组合 从提议的插入。 这些值是使用 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)
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() 方法考虑 Python 端的默认 UPDATE 值或生成函数,例如使用 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)
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 标准


该方法 Insert.on_conflict_do_update() 还接受使用 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)
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


用 DO NOTHING 跳过行


ON CONFLICT 可用于完全跳过插入行 如果发生与 unique 或 exclusion constraint 的任何冲突;下面 这使用 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)
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)
INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s) ON CONFLICT DO NOTHING


仅从 ...


该方言支持 PostgreSQL 的 ONLY 关键字,仅用于定位特定的 table 中。这可用于生成 SELECT ...仅从仅更新 ...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字典中的键是 的 “键” 名称,即用于从 Table.c 集合访问它的名称,可以将其配置为与数据库中表示的列的实际名称不同。


如果要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 的 ExcludeConstraint 中。


索引类型


PostgreSQL 提供了多种索引类型:B-Tree、Hash、GiST 和 GIN 作为用户创建自己的 https://www.postgresql.org/docs/current/static/indexes-types.html)。可以使用 postgresql_using 关键字参数在 Index 上指定这些参数:

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


传递给 keyword 参数的值将简单地传递给底层 CREATE INDEX 命令,因此它必须是您的 PostgreSQL 版本的有效索引类型。


索引存储参数


PostgreSQL 允许在索引上设置存储参数。可用的存储参数取决于索引使用的 index 方法。可以使用 postgresql_withIndex 上指定存储参数 keyword 参数:

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传递给 Index 构造来支持 PostgreSQL 索引选项 CONCURRENTLY

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

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


上述索引构造将把 CREATE INDEX 的 DDL 渲染为(假设检测到 PostgreSQL 8.2 或更高版本)或无连接方言的 DDL,如下所示:

CREATE INDEX CONCURRENTLY test_idx1 ON testtbl (data)


对于 DROP INDEX,假设检测到 PostgreSQL 9.2 或更高版本,或者对于无连接的方言,它将发出:

DROP INDEX CONCURRENTLY test_idx1


使用 CONCURRENT 时,PostgreSQL 数据库要求在事务块外部调用该语句。Python DBAPI 强制要求,即使对于单个语句,也存在事务,因此要使用此构造,必须使用 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 CONSTRAINT 结构。 使用 检查器Inspector.get_indexes() Inspector.get_unique_constraints() 和 将报告这些 两个结构明显;对于索引,键 如果 duplicates_constraint 检测为镜像约束。 使用 Table(..., autoload_with=engine)当检测到 UNIQUE INDEX 镜像 UniqueConstraintTable.constraints 集合中。


特殊反射选项


检查器 用于 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())

对象名称

描述

PGInspector


sqlalchemy.dialects.postgresql.base。PGInspector 浏览器¶

方法 sqlalchemy.dialects.postgresql.base.PGInspector. get_domainsschema:strNone=None List[ReflectedDomain]


返回 DOMAIN 对象的列表。


每个成员都是一个包含以下字段的字典:


  • name — 域的名称


  • 架构 - 域的架构名称。


  • visible - 布尔值,无论此域在默认搜索路径中是否可见。


  • type - 此域定义的类型。


  • nullable - 指示此域是否可以为 NULL。


  • default - 域的默认值,如果域没有默认值,则为 None


  • constraints - 具有此域定义的约束的 dict 列表。每个元素都包含两个键:约束的 namecheck 以及约束文本。


参数


schema – schema 名称。如果为 None,则使用默认架构(通常为 'public')。也可以设置为 '*' 以指示所有架构的加载域。


2.0 版的新Function。


方法 sqlalchemy.dialects.postgresql.base.PGInspector. get_enumsschema:strNone=None List[ReflectedEnum]


返回 ENUM 对象列表。


每个成员都是一个包含以下字段的字典:


  • name - 枚举的名称


  • schema - 枚举的 schema 名称。


  • visible - 布尔值,无论此枚举在默认搜索路径中是否可见。


  • labels - 应用于枚举的字符串标签列表。


参数


schema – schema 名称。如果为 None,则使用默认架构(通常为 'public')。也可以设置为 '*' 以指示所有架构的加载枚举。


方法 sqlalchemy.dialects.postgresql.base.PGInspector. get_foreign_table_namesschema:strNone=None List[str]


返回 FOREIGN TABLE 名称的列表。


行为类似于 Inspector.get_table_names()、 不同之处在于,该列表仅限于报告 relkind 值为 f


方法 sqlalchemy.dialects.postgresql.base.PGInspector. get_table_oidtable_name: str, schema:strNone=None int


返回给定表名的 OID。


参数

  • table_name – 表的字符串名称。对于特殊引用,请使用 quoted_name


  • schema – 字符串 schema name;如果省略,则使用 Database Connection 的默认架构。对于特殊引用,请使用 quoted_name


方法 sqlalchemy.dialects.postgresql.base.PGInspector. has_typetype_name str, schema:strNone=None, **kw Any bool


如果数据库在提供的架构中具有指定的类型,则返回。


参数

  • type_name – 要检查的类型。


  • schema – schema 名称。如果为 None,则使用默认架构(通常为 'public')。也可以设置为 '*' 以签入所有架构。


2.0 版的新Function。


PostgreSQL 表选项


PostgreSQL 方言与 Table 构造一起直接支持 CREATE TABLE 的几个选项:


  • 继承:

    Table("some_table", metadata, ..., postgresql_inherits="some_supertable")
    
    Table("some_table", metadata, ..., postgresql_inherits=("t1", "t2", ...))

  • 提交时

    Table("some_table", metadata, ..., postgresql_on_commit="PRESERVE ROWS")

  • 分区 BY

    Table(
        "some_table",
        metadata,
        ...,
        postgresql_partition_by="LIST (part_column)",
    )


    在 1.2.6 版本加入.


  • TABLESPACE 中:

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


    上述选项在 Index 构造中也可用。


  • 使用:

    Table("some_table", metadata, ..., postgresql_using="heap")


    2.0.26 新版功能.


  • 使用 OIDS

    Table("some_table", metadata, ..., postgresql_with_oids=True)

  • OID

    Table("some_table", metadata, ..., postgresql_with_oids=False)


另请参阅


PostgreSQL 文档中的 PostgreSQL CREATE TABLE 选项


PostgreSQL 约束选项


PostgreSQL 方言与所选约束构造一起支持以下选项:


  • NOT VALID:当通过 ALTER TABLE 将约束添加到现有表时,此选项适用于 CHECK 和 FOREIGN KEY 约束,并且具有在 ALTER作期间不会针对正在添加的约束扫描现有行的效果。


    使用 Alembic 等 SQL 迁移工具时 呈现 ALTER TABLE 构造,则可以在创建约束的作中将 postgresql_not_valid 参数指定为附加关键字参数,如以下 Alembic 示例所示:

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


    关键字最终由 CheckConstraintForeignKeyConstraintForeignKey 结构;当使用像 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 文档中的 PostgreSQL ALTER TABLE 选项


Table 值 , Table 和 Column 值函数 , Row 和 Tuple 对象


PostgreSQL 充分利用了现代 SQL 形式,例如表值函数、表和行作为值。这些结构通常用作 PostgreSQL 对复杂数据类型(如 JSON、ARRAY 和其他数据类型)的支持的一部分。SQLAlchemy 的 SQL 表达式语言对大多数表值和行值形式都有本机支持。


表值函数


许多 PostgreSQL 内置函数旨在用于 FROM 子句 的 SELECT 语句,并且能够返回表行或表集 行。PostgreSQL 的大部分 JSON 函数,例如 json_array_elements()json_object_keys()json_each_text()json_each()、json_to_record()json_populate_recordset() 使用此类形式。SQLAlchemy 中的这些 SQL 函数调用表单类可以使用该方法 FunctionElement.table_valued() 与从 func 生成的 Function 对象结合使用 Namespace。


PostgreSQL 参考文档中的示例如下:


  • json_each()

    >>> from sqlalchemy import select, func
    >>> stmt = select(
    ...     func.json_each('{"a":"foo", "b":"bar"}').table_valued("key", "value")
    ... )
    >>> print(stmt)
    
    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)
    
    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)
    
    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() method 接受一个 keyword 参数with_ordinality 用于此目的,该参数接受将应用于 “ordinality” 列的字符串名称:

    >>> from sqlalchemy import select, func
    >>> stmt = select(
    ...     func.generate_series(4, 1, -1)
    ...     .table_valued("value", with_ordinality="ordinality")
    ...     .render_derived()
    ... )
    >>> print(stmt)
    
    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 版本的新Function。


列值函数


与表值函数类似,列值函数存在于 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)
    
    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)
    
    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)
    
    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)
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)


传递给 Functions 的 Table 类型


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)
SELECT row_to_json(a) AS row_to_json_1 FROM a


1.4.0b2 版本的新Function。


ARRAY 类型


PostgreSQL 方言支持数组,既可以是多维列类型,也可以是数组 Literals:


JSON 类型


PostgreSQL 方言支持 JSON 和 JSONB 数据类型,包括 psycopg2 的原生支持和对所有 PostgreSQL 特殊运算符的支持:


HSTORE 类型


支持 PostgreSQL HSTORE 类型以及 hstore 文本:


ENUM 类型


PostgreSQL 具有可独立创建的 TYPE 结构,用于实现枚举类型。这种方法在 SQLAlchemy 方面引入了相当大的复杂性,即何时应该 CREATE 和 DROPPED。类型对象也是一个可独立反射的实体。应查阅以下部分:


在 ARRAY 中使用 ENUM


目前,后端 DBAPI 不直接支持 ENUM 和 ARRAY 的组合。在 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"))),
)


此类型未作为内置类型包含在内,因为它与突然决定在新版本中直接支持 ENUM 的 ARRAY 的 DBAPI 不兼容。


将 JSON/JSONB 与 ARRAY 一起使用


与使用 ENUM 类似,在 SQLAlchemy 1.3.17 之前,对于 JSON/JSONB 的 ARRAY,我们需要渲染适当的 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)),
)


Range 和 Multirange 类型


psycopg、pg8000 和 asyncpg 方言支持 PostgreSQL range 和 multirange 类型;psycopg2 方言仅支持范围类型。


2.0.17 版本中的新功能: 添加了对 pg8000 方言的范围和多范围支持。需要 pg8000 1.29.8 或更高版本。


传递给数据库的数据值可以作为字符串值传递,也可以使用 Range 数据对象传递。


2.0 版本中的新功能: 添加了与后端无关的范围 对象。 psycopg2 特定的范围类不再公开,仅由该特定方言内部使用。


例如,使用 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 列的数据,范围 type 是一个简单的数据类,它将表示范围的边界。 下面说明了将行插入到上述 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()


从任何范围列中进行选择也将返回范围 objects 所示:

from sqlalchemy import select

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


可用的 range 数据类型如下:


对象名称

描述


范围


表示 PostgreSQL 范围。


sqlalchemy.dialects.postgresql。范围


表示 PostgreSQL 范围。


例如:

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


调用样式类似于 psycopg 和 psycopg2 的调用样式,部分原因是为了更容易地从直接使用这些对象的先前 SQLAlchemy 版本迁移。


参数

  • lower – 下限值,或 None


  • upper- 上限值,或 None


  • bounds– 仅限关键字的可选字符串值,它是以下值之一 “()”、“[)”、“(]”、“[]”。默认为 “[)”。


  • empty – 仅限关键字,可选 bool 表示这是一个 “空” 范围


2.0 版的新Function。


类签名


sqlalchemy.dialects.postgresql.Range 键入。通用


method sqlalchemy.dialects.postgresql.Range. __eq__other Any bool


将此范围与其他范围进行比较,同时考虑边界包容性,如果它们相等,则返回 True


方法 sqlalchemy.dialects.postgresql.Range. adjacent_toother Range[_T] bool


确定此范围是否与其他范围相邻。


方法 sqlalchemy.dialects.postgresql.Range. contained_byother Range[_T] bool


确定此范围是否被 other 包含。


method sqlalchemy.dialects.postgresql.Range. containsvalue:_TRange[_T] bool


确定此范围是否包含 value


方法 sqlalchemy.dialects.postgresql.Range. 差异other Range[_T] Range[_T]


计算此范围与其他范围之间的差异。


如果两个范围是 “disjunct” 的,即既不相邻也不重叠,则会引发 ValueError 异常。


方法 sqlalchemy.dialects.postgresql.Range. intersectionother Range[_T] Range[_T]


计算此范围与其他范围的交集。


在 2.0.10 版本加入.


属性 sqlalchemy.dialects.postgresql.Range. is_empty


'empty' 属性的同义词。

attribute sqlalchemy.dialects.postgresql.Range.isempty


'empty' 属性的同义词。


attribute sqlalchemy.dialects.postgresql.Range. lower:_TNone


下限


属性 sqlalchemy.dialects.postgresql.Range. lower_inc


如果下限是包含的,则返回 True。


属性 sqlalchemy.dialects.postgresql.Range. lower_inf


如果此范围非空且下限为无限,则返回 True。


方法 sqlalchemy.dialects.postgresql.Range. not_extend_left_ofother Range[_T] bool


确定这是否不会延伸到 other 的左侧。


方法 sqlalchemy.dialects.postgresql.Range. not_extend_right_ofother Range[_T] bool


确定这是否不延伸到 other 的右侧。


method sqlalchemy.dialects.postgresql.Range. overlapsother Range[_T] bool


确定此范围是否与其他范围重叠。


方法 sqlalchemy.dialects.postgresql.Range. strictly_left_ofother Range[_T] bool


确定此范围是否完全位于 other 的左侧。


方法 sqlalchemy.dialects.postgresql.Range. strictly_right_ofother Range[_T] bool


确定此范围是否完全位于 other 的右侧。


方法 sqlalchemy.dialects.postgresql.Range. unionother Range[_T] Range[_T]


计算此范围与另一个范围的并集。


如果两个范围是 “disjunct” 的,即既不相邻也不重叠,则会引发 ValueError 异常。


属性 sqlalchemy.dialects.postgresql.Range. upper:_TNone


上限


属性 sqlalchemy.dialects.postgresql.Range. upper_inc


如果上限是非独占的,则返回 True。


属性 sqlalchemy.dialects.postgresql.Range. upper_inf


如果此范围不为空且上限为无限,则返回 True。


多范围


PostgreSQL 14 及更高版本支持多范围。SQLAlchemy 的多范围数据类型处理 Range 类型的列表。


psycopg、asyncpg 和 pg8000 方言支持多范围 。psycopg2 方言,这是 SQLAlchemy 的默认 postgresql dialect 不支持多范围数据类型。


2.0 版本中的新功能: 添加了对 MULTIRANGE 数据类型的支持。 SQLAlchemy 将多范围值表示为 Range 对象。


2.0.17 版本中的新功能: 添加了对 pg8000 方言的多范围支持。需要 pg8000 1.29.8 或更高版本。


2.0.26 版本中的新功能: 添加了 MultiRange 序列。


下面的示例说明了 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]
    added: Mapped[datetime]
    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}")


注意


在上面的示例中,由 ORM 处理的 Range types 列表不会自动检测对特定列表值的就地更改;要使用 ORM 更新列表值,请为属性重新分配新列表,或使用 MutableList type 修饰符。 有关背景信息,请参阅 Mutation Tracking 部分。


使用 MultiRange 序列推断 multirange 类型


当使用多范围作为文本而不指定类型时,可以使用实用程序 MultiRange 序列:

from sqlalchemy import literal
from sqlalchemy.dialects.postgresql import MultiRange

with Session(engine) as session:
    stmt = select(EventCalendar).where(
        EventCalendar.added.op("<@")(
            MultiRange(
                [
                    Range(datetime(2023, 1, 1), datetime(2013, 3, 31)),
                    Range(datetime(2023, 7, 1), datetime(2013, 9, 30)),
                ]
            )
        )
    )
    in_range = session.execute(stmt).all()

with engine.connect() as conn:
    row = conn.scalar(select(literal(MultiRange([Range(2, 4)]))))
    print(f"{row.lower} -> {row.upper}")


使用简单列表而不是 MultiRange 需要手动将文本值的类型设置为适当的 multirange 类型。


2.0.26 版本中的新功能: 添加了 MultiRange 序列。


可用的多范围数据类型如下:


网络数据类型


包含的网络数据类型包括 INETCIDRMACADDR 的 MAC 文件。


对于 INETCIDR 数据类型,这些数据类型提供条件支持,以发送和检索 Python ipaddress 对象,包括 ipaddress。IPv4网络ip地址。IPv6Networkipaddress。IPv4Addressip地址。IPv6地址。此支持目前是 DBAPI 本身,并且因 DBAPI 而异。 SQLAlchemy 尚未实现其 自己的网络地址转换逻辑


  • psycopgasyncpg 完全支持这些数据类型;默认情况下,ipAddress 系列中的对象以行的形式返回。


  • psycopg2 方言只发送和接收字符串。


  • pg8000 方言支持 ipaddress。IPv4Addressip地址。IPv6Address 对象,但CIDR 类型使用字符串。


要将上述所有 DBAPI 规范化为仅返回字符串,请使用 native_inet_types 参数,并传递值 False

e = create_engine(
    "postgresql+psycopg://scott:tiger@host/dbname", native_inet_types=False
)


使用上述参数,psycopgasyncpgpg8000 方言将禁用 DBAPI 对这些类型的适应,并且仅返回字符串,与旧版 psycopg2 方言的行为相匹配。


该参数也可以设置为 True,对于不支持或尚不完全支持将行转换为 Python ipaddress 数据类型(当前为 psycopg2 和 pg8000)的后端,它将引发 NotImplementedError


2.0.18 版本的新Function: - 添加了 native_inet_types 参数。


PostgreSQL 数据类型


与所有 SQLAlchemy 方言一样,所有已知对 PostgreSQL 有效的 UPPERCASE 类型都可以从顶级方言导入,无论它们来自 sqlalchemy.types 还是本地方言:

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


特定于 PostgreSQL 或具有特定于 PostgreSQL 的构造参数的类型如下:


对象名称

描述

AbstractMultiRange


PostgreSQL MULTIRANGE 类型的基础。


抽象范围


单范围 SQL 类型和多范围 SQL 类型的基类。

AbstractSingleRange


PostgreSQL RANGE 类型的基础。

ARRAY


PostgreSQL ARRAY 类型。

BIT

BYTEA

CIDR

CITEXT


提供 PostgreSQL CITEXT 类型。

DATEMULTIRANGE


表示 PostgreSQL DATEMULTIRANGE 类型。

DATERANGE


表示 PostgreSQL DATERANGE 类型。

DOMAIN


表示 DOMAIN PostgreSQL 类型。

ENUM


PostgreSQL ENUM 类型。

HSTORE


表示 PostgreSQL HSTORE 类型。

INET

INT4MULTIRANGE


表示 PostgreSQL INT4MULTIRANGE类型。

INT4RANGE


表示 PostgreSQL INT4RANGE类型。

INT8MULTIRANGE


表示 PostgreSQL INT8MULTIRANGE类型。

INT8RANGE


表示 PostgreSQL INT8RANGE类型。

INTERVAL


PostgreSQL INTERVAL 类型。

JSON


表示 PostgreSQL JSON 类型。

JSONB


表示 PostgreSQL JSONB 类型。

JSONPATH


JSON 路径类型。

MACADDR

MACADDR8

MONEY


提供 PostgreSQL MONEY 类型。


多范围


表示多范围序列。

NUMMULTIRANGE


表示 PostgreSQL NUMMULTIRANGE 类型。

NUMRANGE


表示 PostgreSQL NUMRANGE 类型。

OID


提供 PostgreSQL OID 类型。

REGCLASS


提供 PostgreSQL REGCLASS 类型。

REGCONFIG


提供 PostgreSQL REGCONFIG 类型。

TIME


PostgreSQL TIME 类型。

TIMESTAMP


提供 PostgreSQL TIMESTAMP 类型。

TSMULTIRANGE


表示 PostgreSQL TSRANGE 类型。

TSQUERY


提供 PostgreSQL TSQUERY 类型。

TSRANGE


表示 PostgreSQL TSRANGE 类型。

TSTZMULTIRANGE


表示 PostgreSQL TSTZRANGE 类型。

TSTZRANGE


表示 PostgreSQL TSTZRANGE 类型。

TSVECTOR


TSVECTOR 类型实现 PostgreSQL 文本搜索类型 TSVECTOR。


sqlalchemy.dialects.postgresql。抽象范围


单范围 SQL 类型和多范围 SQL 类型的基类。


comparator_factory


定义范围类型的比较作。


类签名


sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory sqlalchemy.types.Comparator


方法 sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory. adjacent_toother Any ColumnElement[bool]


布尔表达式。如果列中的区域与作数中的区域相邻,则返回 true。


方法 sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory. contained_byother Any ColumnElement[bool]


布尔表达式。如果列包含在右侧作数中,则返回 true。


method sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory. containsother Any**kw Any ColumnElement[bool]


布尔表达式。如果右侧作数(可以是元素或范围)包含在列中,则返回 true。


kwargs 可以被此运算符忽略,但对于 API 一致性是必需的。


方法 sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory. 差异other Any ColumnElement[bool]


Range 表达式。返回两个范围的并集。如果结果范围不连续,将引发异常。


方法 sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory. intersectionother Any ColumnElement[Range[_T]


Range 表达式。返回两个范围的交集。如果结果范围不连续,将引发异常。


方法 sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory. not_extend_left_ofother Any ColumnElement[bool]


布尔表达式。如果列中的范围未超出作数中范围的左侧,则返回 true。


方法 sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory. not_extend_right_ofother Any ColumnElement[bool]


布尔表达式。如果列中的范围未扩展作数中范围的右侧,则返回 true。


method sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory. overlapsother Any ColumnElement[bool]


布尔表达式。如果列与右侧作数重叠(具有共同点),则返回 true。


方法 sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory. strictly_left_ofother Any ColumnElement[bool]


布尔表达式。如果列严格位于右侧作数的左侧,则返回 true。


方法 sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory. strictly_right_ofother Any ColumnElement[bool]


布尔表达式。如果列严格位于右侧作数的右侧,则返回 true。


方法 sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory. unionother Any ColumnElement[bool]


Range 表达式。返回两个范围的并集。如果结果范围不连续,将引发异常。


sqlalchemy.dialects.postgresql。抽象单范围


PostgreSQL RANGE 类型的基础。


这些类型返回单个 Range 对象。


sqlalchemy.dialects.postgresql。抽象多范围


PostgreSQL MULTIRANGE 类型的基础。


这些类型返回 Range 序列 对象。


sqlalchemy.dialects.postgresql。数组


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() 中。数组 类也 提供特定于 PostgreSQL 的包含作方法,包括 Comparator.contains()Comparator.contained_by()Comparator.overlap()的 Cookie 中,例如:

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


默认情况下,索引访问是从 1 开始的,以匹配 PostgreSQL 的访问; 对于从零开始的索引访问,将 ARRAY.zero_indexes


此外,ARRAY type 不能直接在 与 ENUM 类型结合使用。有关解决方法,请参阅将 ENUM 与 ARRAY 结合使用中的特殊类型。


使用 ORM 时检测 ARRAY 列中的更改


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() 以生成工作单元将检测到的事件。请注意,不会检测到对数组元素的更改,包括就地更改的子数组。


或者,将新的数组值分配给替换旧 ORM 元素的 ORM 元素将始终触发 change 事件。


另请参阅


ARRAY - 基本数组类型


array - 生成文本数组值。


方法 sqlalchemy.dialects.postgresql.ARRAY. __init__item_type _TypeEngineArgument[Any]as_tuple: bool = False, dimensions:intNone=None, zero_indexes: bool = False


构造一个 ARRAY。


例如:

Column("myarray", ARRAY(Integer))


参数是:


参数

  • item_type- 此数组的 items 的数据类型。请注意, 维数在这里无关紧要,因此像 INTEGER[][] 构造为 ARRAY(Integer),而不是 ARRAY(ARRAY(Integer)) 等。


  • as_tuple=False- 指定是否应将返回结果转换为列表中的元组。默认情况下,DBAPI(如 psycopg2)会返回列表。当返回 Tuples 时,结果是可哈希的。


  • dimensions——如果非 None,则 ARRAY 将采用固定数量的维度。这将导致为此 ARRAY 发出的 DDL 包含方括号子句 [] 的确切数量,并且还将优化该类型的整体性能。请注意,PG 数组始终是隐式的 “无量纲” ,这意味着它们可以存储任意数量的维度,无论它们是如何声明的。


  • zero_indexes=False – 当为 True 时,索引值将在 Python 基于 0 的索引和 PostgreSQL 基于 1 的索引之间转换,例如,在传递到数据库之前,将值 1 添加到所有索引值中。


Comparator


定义 ARRAY 的比较作。


请注意,这些作是对基类 Comparator 提供的作的补充,包括 Comparator.any()Comparator.all() 中。


类签名


sqlalchemy.dialects.postgresql.ARRAY.Comparator sqlalchemy.types.Comparator


method sqlalchemy.dialects.postgresql.ARRAY.Comparator. containsother**kwargs


布尔表达式。测试 elements 是否是 argument array 表达式的元素的超集。


kwargs 可以被此运算符忽略,但对于 API 一致性是必需的。


方法 sqlalchemy.dialects.postgresql.ARRAY.Comparator. contained_by其他


布尔表达式。测试 elements 是否是 argument array 表达式的元素的适当子集。


方法 sqlalchemy.dialects.postgresql.ARRAY.Comparator. overlapother


布尔表达式。测试 array 是否具有与参数 array 表达式相同的元素。


sqlalchemy.dialects.postgresql。位元

sqlalchemy.dialects.postgresql。BYTEA 浏览器¶

方法 sqlalchemy.dialects.postgresql.BYTEA. __init__length:intNone=None


继承自 sqlalchemy.types.LargeBinary.__init__ LargeBinary 的方法


构造 LargeBinary 类型。


参数


length – 可选,用于 DDL 语句的列的长度,适用于接受长度的二进制类型,例如 MySQL BLOB 类型。


sqlalchemy.dialects.postgresql。CIDR (数据归档) ¶

sqlalchemy.dialects.postgresql。CITEXT的翻译¶


提供 PostgreSQL CITEXT 类型。


2.0.7 新版功能.


方法 sqlalchemy.dialects.postgresql.CITEXT. __init__length:intNone=None, collation:strNone=None


继承自 sqlalchemy.types.String.__init__ String 的方法


创建字符串保持类型。


参数

  • length – 可选,用于 DDL 和 CAST 表达式的列的长度。如果没有 CREATE ,则可以安全地省略 桌子将发布。 某些数据库可能需要 length 在 DDL 中使用,如果 VARCHAR 不包括长度。 值是否为 解释为 bytes 或 characters 是特定于数据库的。


  • 排序规则


    可选,用于 DDL 和 CAST 表达式的列级排序规则。使用 SQLite、MySQL 和 PostgreSQL 支持的 COLLATE 关键字进行渲染。例如:

    >>> from sqlalchemy import cast, select, String
    >>> print(select(cast("some string", String(collation="utf8"))))
    
    SELECT CAST(:param_1 AS VARCHAR COLLATE utf8) AS anon_1


    注意


    在大多数情况下,UnicodeUnicodeText 数据类型应用于预期存储非 ASCII 数据的 Column。这些数据类型将确保在数据库上使用正确的类型。


sqlalchemy.dialects.postgresql。


表示 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 文档


2.0 版的新Function。


类签名


sqlalchemy.dialects.postgresql.DOMAIN sqlalchemy.dialects.postgresql.named_types.NamedTypesqlalchemy.types.SchemaType


方法 sqlalchemy.dialects.postgresql.DOMAIN. __init__name strdata_type: _TypeEngineArgument[Any]*、 collation:strNone=None、 default:elements 。TextClausestrNone=无, constraint_name:strNone=无, not_null:boolNone=无, check:elements.TextClausestrNone=None, create_type: bool = True**kw Any


构造 DOMAIN。


参数

  • name¶(名称)¶ – 域的名称


  • data_type– 域的基础数据类型。这可以包括数组说明符。


  • collation– 域的可选排序规则。 如果未指定排序规则,则基础数据类型的默认值 排序规则。如果 collation 指定。


  • default– DEFAULT 子句指定 domain 数据类型的列的默认值。默认值应为 string 或 text() 值。如果未指定默认值,则默认值为 null 值。


  • constraint_name– 约束的可选名称。如果未指定,后端将生成一个名称。


  • not_null – 此域的值不能为 null。默认情况下,domain 允许为 null。如果未指定,则不会发出 nullability 子句。


  • check– CHECK 子句指定完整性约束或测试域的哪些值必须满足。约束必须是生成布尔结果的表达式,该结果可以使用关键字 VALUE 来引用正在测试的值。与 PostgreSQL 不同,SQLAlchemy 中当前只允许使用单个 check 子句。


  • schema – 可选的 schema 名称


  • metadata– 此 DOMAIN 将直接关联的可选 MetaData 对象


  • create_type – 默认为 True。指示在创建父表时,在选择性地检查类型是否存在之后,应发出 CREATE TYPE;此外,在删除表时调用 DROP TYPE


方法 sqlalchemy.dialects.postgresql.DOMAIN. createbindcheckfirst=True**kw


继承自 NamedTypeNamedType.create() 方法


为此类型发出 CREATE DDL。


参数

  • bind—— 一个可连接的引擎Connection 或类似对象来发出 SQL。


  • checkfirst——如果为 True,则首先对 PG 目录执行查询,以查看该类型是否在创建之前不存在。


方法 sqlalchemy.dialects.postgresql.DOMAIN. dropbindcheckfirst=True**kw


继承自 NamedTypeNamedType.drop() 方法


为此类型发出 DROP DDL。


参数

  • bind—— 一个可连接的引擎Connection 或类似对象来发出 SQL。


  • checkfirst—— 如果为 True,则首先对 PG 目录执行查询,以查看该类型是否确实存在,然后再删除。


sqlalchemy.dialects.postgresql。DOUBLE_PRECISION


SQL DOUBLE PRECISION 类型。


2.0 版的新Function。


另请参阅


Double - 基本类型的文档。


类签名


sqlalchemy.dialects.postgresql.DOUBLE_PRECISIONsqlalchemy.types.Double


方法 sqlalchemy.dialects.postgresql.DOUBLE_PRECISION. __init__precision:intNone=None, asdecimal bool = False, decimal_return_scale:intNone=None


继承自 sqlalchemy.types.Float.__init__ Float 的方法


构造一个浮点数。


参数

  • 精度


    在 DDL CREATE 中使用的数值精度 TABLE 的后端尝试确保此精度 表示泛型 Float 数据类型。


    注意


    对于 Oracle Database 后端, 渲染 DDL 时不接受 Float.precision 参数,因为 Oracle Database 不支持指定为小数位数的浮点精度。相反,请使用特定于 Oracle Database 的 FLOAT 数据类型并指定 FLOAT.binary_precision 参数。这是 SQLAlchemy 版本 2.0 中的新增功能。


    要创建与数据库无关的 Float,请执行 单独指定 Oracle Database 的二进制精度,请使用 TypeEngine.with_variant() 如下所示:

    from sqlalchemy import Column
    from sqlalchemy import Float
    from sqlalchemy.dialects import oracle
    
    Column(
        "float_data",
        Float(5).with_variant(oracle.FLOAT(binary_precision=16), "oracle"),
    )


  • asdecimal —— 与 Numeric 的标志相同,但默认为 False。请注意,将此标志设置为 True 导致浮点转换。


  • decimal_return_scale– 从浮点数转换为 Python 小数时使用的默认比例。由于十进制的不准确,浮点值通常会长得多,并且大多数浮点数据库类型没有“小数位数”的概念,因此默认情况下,浮点类型在转换时查找前十位小数。指定此值将覆盖该长度。请注意,如果未另行指定,则包含 “scale” 的 MySQL 浮点类型将使用 “scale” 作为 decimal_return_scale 的默认值。


sqlalchemy.dialects.postgresql。枚举


PostgreSQL ENUM 类型。


这是 Enum 的子类,包括对 PG 的 CREATE TYPEDROP TYPE 的支持。


当使用内置类型 Enum 并且 Enum.native_enum标志保留为默认值 True,则 PostgreSQL 后端将使用 ENUM type 作为实现,因此特殊的 create/drop 规则 将被使用。


由于 ENUM 类型与父表的关系很尴尬,因此 ENUM 的创建/删除行为必然是复杂的,因为它可能仅由单个表“拥有”,也可能在许多表之间共享。


使用 EnumENUM 时 以“内联”方式,CREATE TYPEDROP 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


要在多个表之间使用通用枚举类型,最佳实践是将 EnumENUM 的 URL,并将其与 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))


使用此模式时,仍必须在单个 table 创建级别上小心。发出 CREATE TABLE 而不指定 checkfirst=True 仍会导致问题:

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


如果我们指定 checkfirst=True,则单个表级创建作将检查 ENUM 并在不存在时创建 create:

# 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)


类签名


sqlalchemy.dialects.postgresql.ENUM sqlalchemy.dialects.postgresql.named_types.NamedTypesqlalchemy.types.NativeForEmulated , sqlalchemy.types.Enum


方法 sqlalchemy.dialects.postgresql.ENUM. __init__*enums, name:str_NoArgNone=_NoArg.NO_ARG, create_type: bool = True**kw


构造 ENUM


参数与 Enum 的 Lenum 方法,但也包括以下参数。


参数


create_type – 默认为 True。指示在创建父表时,在选择性地检查类型是否存在之后,应发出 CREATE TYPE;此外,在删除表时调用 DROP TYPE。当 False 时,将不执行任何检查,也不执行 CREATE TYPEDROP TYPE 发出,除非 ENUM.create()ENUM.drop() 直接调用。 在无法访问实际数据库的情况下对 SQL 文件调用创建方案时,设置为 False 非常有用 - ENUM.create()ENUM.drop() 方法可用于将 SQL 发送到目标绑定。


method sqlalchemy.dialects.postgresql.ENUM. createbind=Nonecheckfirst=True


为此发出 CREATE TYPE 枚举。


如果底层方言不支持 PostgreSQL CREATE TYPE,则不会执行任何作。


参数

  • bind—— 一个可连接的引擎Connection 或类似对象来发出 SQL。


  • checkfirst——如果为 True,则首先对 PG 目录执行查询,以查看该类型是否在创建之前不存在。


method sqlalchemy.dialects.postgresql.ENUM. dropbind=Nonecheckfirst=True


为此发出 DROP TYPE 枚举。


如果底层方言不支持 PostgreSQL DROP TYPE,则不会执行任何作。


参数

  • bind—— 一个可连接的引擎Connection 或类似对象来发出 SQL。


  • checkfirst—— 如果为 True,则首先对 PG 目录执行查询,以查看该类型是否确实存在,然后再删除。


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


使用 ORM 时检测 HSTORE 列中的更改


为了与 SQLAlchemy ORM 一起使用,可能需要将 HSTOREMutableDict 字典结合使用,现在是 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 属性本身,从而生成更改事件。


另请参阅


hstore - 呈现 PostgreSQL hstore() 函数。


Comparator


定义 HSTORE 的比较运算。


类签名


sqlalchemy.dialects.postgresql.HSTORE.Comparator sqlalchemy.types.Comparatorsqlalchemy.types.Comparator


方法 sqlalchemy.dialects.postgresql.HSTORE.Comparator. array


文本数组表达式。返回交替键和值的数组。


方法 sqlalchemy.dialects.postgresql.HSTORE.Comparator. contained_by其他


布尔表达式。测试 keys 是否是参数 jsonb 表达式的 keys 的正确子集。


method sqlalchemy.dialects.postgresql.HSTORE.Comparator. containsother**kwargs


布尔表达式。测试 keys (或数组) 是否是参数 jsonb 表达式的 keys 的超集/包含。


kwargs 可以被此运算符忽略,但对于 API 一致性是必需的。


method sqlalchemy.dialects.postgresql.HSTORE.Comparator. definedkey)¶


布尔表达式。测试键是否存在非 NULL 值。请注意,键可以是 SQLA 表达式。


方法 sqlalchemy.dialects.postgresql.HSTORE.Comparator. deletekey


HStore 表达式。返回已删除给定键的此 hstore 的内容。请注意,键可以是 SQLA 表达式。


方法 sqlalchemy.dialects.postgresql.HSTORE.Comparator. has_all其他


布尔表达式。测试 jsonb 中是否存在所有键


方法 sqlalchemy.dialects.postgresql.HSTORE.Comparator. has_any其他


布尔表达式。测试 jsonb 中是否存在任何键


方法 sqlalchemy.dialects.postgresql.HSTORE.Comparator. has_key其他


布尔表达式。测试是否存在密钥。请注意,键可以是 SQLA 表达式。


方法 sqlalchemy.dialects.postgresql.HSTORE.Comparator. keys


文本数组表达式。返回 key 数组。


方法 sqlalchemy.dialects.postgresql.HSTORE.Comparator. matrix


文本数组表达式。返回 [key, value] 对的数组。


方法 sqlalchemy.dialects.postgresql.HSTORE.Comparator. slicearray


HStore 表达式。返回由 Array of keys 定义的 hstore 的子集。


方法 sqlalchemy.dialects.postgresql.HSTORE.Comparator. vals


文本数组表达式。返回值数组。


方法 sqlalchemy.dialects.postgresql.HSTORE. __init__text_type=None


构建新的 HSTORE


参数


text_type – 应该用于索引值的类型。默认为 Text


方法 sqlalchemy.dialects.postgresql.HSTORE. bind_processor方言


返回用于处理绑定值的转换函数。


返回一个可调用对象,该对象将接收一个 bind 参数值作为唯一的位置参数,并将返回一个值以发送到 DB-API。


如果不需要处理,该方法应返回 None


注意


此方法仅相对于 dialect 特定类型调用 object,它通常是正在使用的方言私有的,并且与面向公众的对象不是同一类型对象,这意味着为了提供替代 TypeEngine.bind_processor() 而将 TypeEngine 类子类化是不可行的 方法,除非将 UserDefinedType 子类化 类。


要为 TypeEngine.bind_processor()中,实现 TypeDecorator 类并提供 TypeDecorator.process_bind_param() .


另请参阅


扩充现有类型


参数


dialect– 正在使用的 Dialect 实例。


属性 sqlalchemy.dialects.postgresql.HSTORE. comparator_factory


Comparator 的别名

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


Flag(如果为 False),则表示此类型的值不可哈希。


由 ORM 在显示结果列表时使用。


方法 sqlalchemy.dialects.postgresql.HSTORE. result_processordialectcoltype


返回用于处理结果行值的转换函数。


返回一个可调用对象,该对象将接收结果行列值作为唯一的位置参数,并将返回一个值以返回给用户。


如果不需要处理,该方法应返回 None


注意


此方法仅相对于 dialect 特定类型调用 object,它通常是正在使用的方言私有的,并且与面向公众的对象不是同一类型对象,这意味着为了提供替代 TypeEngine.result_processor() 而将 TypeEngine 类子类化是不可行的 方法,除非将 UserDefinedType 子类化 类。


要为 TypeEngine.result_processor()中,实现 TypeDecorator 类并提供 TypeDecorator.process_result_value() .


另请参阅


扩充现有类型


参数

  • dialect– 正在使用的 Dialect 实例。


  • coltype– 在 cursor.description 中接收的 DBAPI coltype 参数。


sqlalchemy.dialects.postgresql。INET

sqlalchemy.dialects.postgresql。间隔


PostgreSQL INTERVAL 类型。


类签名


sqlalchemy.dialects.postgresql.INTERVAL sqlalchemy.types.NativeForEmulatedsqlalchemy.types._AbstractInterval


方法 sqlalchemy.dialects.postgresql.INTERVAL. __init__precision:intNone=None, fields:strNone=None None


构造一个 INTERVAL.


参数

  • precision – 可选的整数精度值


  • 字段


    string fields 说明符。允许限制字段的存储,例如 “YEAR”、“MONTH”、“DAY TO HOUR” 等。


    在 1.2 版本加入.


sqlalchemy.dialects.postgresql。JSON格式¶


表示 PostgreSQL JSON 类型。


每当 base JSON 数据类型用于 PostgreSQL 后端,但基本 JSON 数据类型不提供 Python 特定于 PostgreSQL 的比较方法(例如 比较器.astext();此外,要使用 PostgreSQL JSONB,应显式使用 JSONB 数据类型。


另请参阅


JSON - 通用跨平台 JSON 数据类型的主要文档。


PostgreSQL 版 JSON 提供的运算符 包括:


  • 索引作(-> 运算符):

    data_table.c.data["some key"]
    
    data_table.c.data[5]

  • 返回文本的索引作(->> 运算符):

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


    请注意,可通过 Comparator.as_string 访问器。


  • 使用 CAST 的索引作(相当于 CAST(col ->> ['some key'] AS <type>) ):

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


    请注意,可通过 Comparator.as_integer 和类似的访问器。


  • 路径索引作(#> 运算符):

    data_table.c.data[("key_1", "key_2", 5, ..., "key_n")]

  • 返回文本的路径索引作(#>> 运算符):

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


索引作返回一个表达式对象,其类型默认为 JSON,以便对结果类型调用进一步的面向 JSON 的指令。


自定义序列化器和反序列化器是在方言级别指定的,即使用 create_engine()。这样做的原因是,在使用 psycopg2 时,DBAPI 只允许每个游标或每个连接级别的序列化器。例如:

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


使用 psycopg2 方言时,使用 psycopg2.extras.register_default_json json_deserializer.


另请参阅


JSON - 核心级别 JSON 类型


JSONB 格式


Comparator


定义 JSON 的比较作。


类签名


sqlalchemy.dialects.postgresql.JSON.Comparator sqlalchemy.types.Comparator


属性 sqlalchemy.dialects.postgresql.JSON.Comparator. 为 Text


在索引表达式上,在 SQL 中呈现时使用 “astext” (例如 “->>”) 转换。


例如:

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

方法 sqlalchemy.dialects.postgresql.JSON. __init__none_as_null=Falseastext_type=None


构造 JSON 类型。


参数
  • none_as_null


    如果为 True,则将值 None 保留为 SQL NULL 值,而不是 null 的 JSON 编码。请注意,当此标志为 False 时,null() 构造仍可用于保留 NULL 值:

    from sqlalchemy import null
    
    conn.execute(table.insert(), {"data": null()})


  • astext_type – 用于 比较器.astext 索引属性上的访问器。 默认为 Text


属性 sqlalchemy.dialects.postgresql.JSON. comparator_factory


Comparator 的别名


属性 sqlalchemy.dialects.postgresql.JSON. render_bind_cast = True


渲染 BindTyping.RENDER_CASTS 模式的绑定强制转换。


如果为 True,则此类型(通常是方言级别的 impl 类型)向编译器发出信号,表明应围绕此类型的绑定参数呈现强制转换。


2.0 版的新Function。


另请参阅


绑定类型


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 type 未检测 in-place 更改,除非 sqlalchemy.ext.mutable 扩展名。


自定义序列化器和反序列化器使用 JSON 类共享json_serializerjson_deserializer 关键字参数。这些必须使用 create_engine() 在方言级别指定。 使用 psycopg2 中,序列化器使用 psycopg2.extras.register_default_jsonb 基于每个连接,与使用 JSON 类型注册这些处理程序的方式相同 psycopg2.extras.register_default_json


另请参阅


JSON 格式


Comparator


定义 JSON 的比较作。


类签名


sqlalchemy.dialects.postgresql.JSONB.Comparator sqlalchemy.dialects.postgresql.json.Comparator


方法 sqlalchemy.dialects.postgresql.JSONB.Comparator. contained_by其他


布尔表达式。测试 keys 是否是参数 jsonb 表达式(相当于 <@ 运算符)的键的正确子集。


method sqlalchemy.dialects.postgresql.JSONB.Comparator. containsother**kwargs


布尔表达式。测试 keys (或数组) 是否是参数 jsonb 表达式(相当于 @> 运算符)的 keys 的超集/包含。


kwargs 可以被此运算符忽略,但对于 API 一致性是必需的。


方法 sqlalchemy.dialects.postgresql.JSONB.Comparator. delete_patharray


JSONB 表达式。删除参数数组中指定的字段或数组元素(相当于 #- 运算符)。


输入可能是一个字符串列表,这些字符串将被强制转换为 ARRAY_postgres.array() 的实例。


2.0 版的新Function。


方法 sqlalchemy.dialects.postgresql.JSONB.Comparator. has_all其他


布尔表达式。测试jsonb中是否存在所有键(相当于?&运算符)


方法 sqlalchemy.dialects.postgresql.JSONB.Comparator. has_any其他


布尔表达式。测试 jsonb 中是否存在任何键(相当于 ?| 运算符)


方法 sqlalchemy.dialects.postgresql.JSONB.Comparator. has_key其他


布尔表达式。测试是否存在密钥(相当于 运算符)。请注意,键可以是 SQLA 表达式。


方法 sqlalchemy.dialects.postgresql.JSONB.Comparator. path_exists其他


布尔表达式。测试是否存在由参数 JSONPath 表达式(相当于 @? 运算符)给出的项目。


2.0 版的新Function。


方法 sqlalchemy.dialects.postgresql.JSONB.Comparator. path_match其他


布尔表达式。测试参数 JSONPath 表达式给定的 JSONPath 谓词是否匹配(相当于 @@ 运算符)。


仅考虑结果的第一项。


2.0 版的新Function。


属性 sqlalchemy.dialects.postgresql.JSONB. comparator_factory


Comparator 的别名


sqlalchemy.dialects.postgresql。JSONPATH的¶


JSON 路径类型。


当使用 json 搜索时,通常需要将文本值转换为 json 路径,例如 jsonb_path_query_arrayjsonb_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


sqlalchemy.dialects.postgresql。MACADDR 的¶

sqlalchemy.dialects.postgresql。MACADDR8

sqlalchemy.dialects.postgresql。货币


提供 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


或者,可以使用以下 TypeDecorator.column_expression() 方法将转换作为 CAST 应用:

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。OID


提供 PostgreSQL OID 类型。


sqlalchemy.dialects.postgresql。真正


SQL REAL 类型。


另请参阅


Float - 基本类型的文档。


类签名


sqlalchemy.dialects.postgresql.REALsqlalchemy.types.Float


方法 sqlalchemy.dialects.postgresql.REAL. __init__precision:intNone=None, asdecimal bool = False, decimal_return_scale:intNone=None


继承自 sqlalchemy.types.Float.__init__ Float 的方法


构造一个浮点数。


参数

  • 精度


    在 DDL CREATE 中使用的数值精度 TABLE 的后端尝试确保此精度 表示泛型 Float 数据类型。


    注意


    对于 Oracle Database 后端, 渲染 DDL 时不接受 Float.precision 参数,因为 Oracle Database 不支持指定为小数位数的浮点精度。相反,请使用特定于 Oracle Database 的 FLOAT 数据类型并指定 FLOAT.binary_precision 参数。这是 SQLAlchemy 版本 2.0 中的新增功能。


    要创建与数据库无关的 Float,请执行 单独指定 Oracle Database 的二进制精度,请使用 TypeEngine.with_variant() 如下所示:

    from sqlalchemy import Column
    from sqlalchemy import Float
    from sqlalchemy.dialects import oracle
    
    Column(
        "float_data",
        Float(5).with_variant(oracle.FLOAT(binary_precision=16), "oracle"),
    )


  • asdecimal —— 与 Numeric 的标志相同,但默认为 False。请注意,将此标志设置为 True 导致浮点转换。


  • decimal_return_scale– 从浮点数转换为 Python 小数时使用的默认比例。由于十进制的不准确,浮点值通常会长得多,并且大多数浮点数据库类型没有“小数位数”的概念,因此默认情况下,浮点类型在转换时查找前十位小数。指定此值将覆盖该长度。请注意,如果未另行指定,则包含 “scale” 的 MySQL 浮点类型将使用 “scale” 作为 decimal_return_scale 的默认值。


sqlalchemy.dialects.postgresql。REGCONFIG


提供 PostgreSQL REGCONFIG 类型。


2.0.0rc1 版本的新Function。


sqlalchemy.dialects.postgresql。REGCLASS


提供 PostgreSQL REGCLASS 类型。


在 1.2.7 版本加入.


sqlalchemy.dialects.postgresql。时间戳


提供 PostgreSQL TIMESTAMP 类型。


方法 sqlalchemy.dialects.postgresql.TIMESTAMP. __init__timezone bool = False, precision:intNone=None) None


构造一个 TIMESTAMP。


参数

  • timezone- 如果存在时区,则为布尔值,默认为 False


  • 精度


    可选的整数精度值


    在 1.4 版本加入.


sqlalchemy.dialects.postgresql。时间


PostgreSQL TIME 类型。


方法 sqlalchemy.dialects.postgresql.TIME. __init__timezone bool = False, precision:intNone=None) None


构造一个 TIME。


参数

  • timezone- 如果存在时区,则为布尔值,默认为 False


  • 精度


    可选的整数精度值


    在 1.4 版本加入.


sqlalchemy.dialects.postgresql。TSQUERY的¶


提供 PostgreSQL TSQUERY 类型。


2.0.0rc1 版本的新Function。


sqlalchemy.dialects.postgresql。TSVECTOR


TSVECTOR 类型实现 PostgreSQL 文本搜索类型 TSVECTOR。


它可用于对自然语言文档进行全文查询。


另请参阅


全文搜索


sqlalchemy.dialects.postgresql。UUID


表示 SQL UUID 类型。


这是 UUID 数据库不可知数据类型的 SQL 原生形式,并且向后兼容以前仅限 PostgreSQL 的 UUID 版本。


UUID 数据类型仅适用于具有名为 UUID 的 SQL 数据类型的数据库。它不适用于没有此精确命名类型的后端,包括 SQL Server。对于具有本机支持的后端不可知的 UUID 值,包括 SQL Server 的 UNIQUEIDENTIFIER datatype 中,请使用 Uuid 数据类型。


2.0 版的新Function。


另请参阅



类签名


sqlalchemy.dialects.postgresql.UUIDsqlalchemy.types.Uuidsqlalchemy.types.NativeForEmulated


方法 sqlalchemy.dialects.postgresql.UUID. __init__as_uuid: bool = True


构造 UUID 类型。


参数


as_uuid=真


如果为 True,则值将被解释为 Python uuid 对象,通过 DBAPI 与字符串相互转换。


sqlalchemy.dialects.postgresql。INT4RANGE


表示 PostgreSQL INT4RANGE类型。


sqlalchemy.dialects.postgresql。INT8RANGE


表示 PostgreSQL INT8RANGE类型。


sqlalchemy.dialects.postgresql。NUMRANGE


表示 PostgreSQL NUMRANGE 类型。


sqlalchemy.dialects.postgresql。日期范围


表示 PostgreSQL DATERANGE 类型。


sqlalchemy.dialects.postgresql。TSRANGE的¶


表示 PostgreSQL TSRANGE 类型。


sqlalchemy.dialects.postgresql。TSTZRANGE的¶


表示 PostgreSQL TSTZRANGE 类型。


sqlalchemy.dialects.postgresql。INT4MULTIRANGE


表示 PostgreSQL INT4MULTIRANGE类型。


sqlalchemy.dialects.postgresql。INT8MULTIRANGE


表示 PostgreSQL INT8MULTIRANGE类型。


sqlalchemy.dialects.postgresql。NUMMULTIRANGE的¶


表示 PostgreSQL NUMMULTIRANGE 类型。


sqlalchemy.dialects.postgresql。DATEMULTIRANGE


表示 PostgreSQL DATEMULTIRANGE 类型。


sqlalchemy.dialects.postgresql。TSMULTIRANGE¶


表示 PostgreSQL TSRANGE 类型。


sqlalchemy.dialects.postgresql。TSTZMULTIRANGE


表示 PostgreSQL TSTZRANGE 类型。


sqlalchemy.dialects.postgresql。多范围


表示多范围序列。


此列表子类是一个实用程序,允许根据单个范围值对适当的多范围 SQL 类型进行自动类型推理。这在对 Literal multi-ranges 进行作时很有用:

import sqlalchemy as sa
from sqlalchemy.dialects.postgresql import MultiRange, Range

value = literal(MultiRange([Range(2, 4)]))

select(tbl).where(tbl.c.value.op("@")(MultiRange([Range(-3, 7)])))


2.0.26 新版功能.


类签名


class sqlalchemy.dialects.postgresql.MultiRange builtins.listtyping.通用


PostgreSQL SQL 元素和函数


对象名称

描述

aggregate_order_by


表示 PostgreSQL 聚合 order by 表达式。


All(其他, arrexpr[, 运算符])


ARRAY 级 Comparator.all() 方法的同义词。有关详细信息,请参阅该方法。


Any(其他, arrexpr[, 运算符])


ARRAY 级 Comparator.any() 方法的同义词。有关详细信息,请参阅该方法。


数组


PostgreSQL ARRAY 文本。


array_agg(*arg, **kw)


特定于 PostgreSQL 的 array_agg形式,确保返回类型是 ARRAY 而不是普通 ARRAY,除非显式type_ 被传递。


HStret


使用 PostgreSQL hstore() 函数在 SQL 表达式中构造 hstore 值。

phraseto_tsquery


PostgreSQL phraseto_tsquery SQL 函数。

plainto_tsquery


PostgreSQL plainto_tsquery SQL 函数。

to_tsquery


PostgreSQL to_tsquery SQL 函数。

to_tsvector


PostgreSQL to_tsvector SQL 函数。

ts_headline


PostgreSQL ts_headline SQL 函数。

websearch_to_tsquery


PostgreSQL websearch_to_tsquery SQL 函数。


sqlalchemy.dialects.postgresql。aggregate_order_by


表示 PostgreSQL 聚合 order by 表达式。


例如:

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 版本发生变更: - ORDER BY 参数可以是多个术语


另请参阅

array_agg


sqlalchemy.dialects.postgresql。数组


PostgreSQL ARRAY 文本。


这用于在 SQL 表达式中生成 ARRAY 文字,例如:

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的 ARRAY 中。数组的 “inner” 类型是从存在的值推断出来的,除非传递了 type_ 关键字参数:

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


多维数组是通过嵌套数组构造生成的。最终 ARRAY 的维度 type 的计算方式为 递归添加内部 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


函数 sqlalchemy.dialects.postgresql。array_agg*arg**kw)¶


特定于 PostgreSQL 的 array_agg形式,确保返回类型是 ARRAY 而不是普通 ARRAY,除非显式type_ 被传递。


函数 sqlalchemy.dialects.postgresql。Anyotherarrexproperator=<内置函数 eq>


ARRAY 级 Comparator.any() 方法的同义词。有关详细信息,请参阅该方法。


函数 sqlalchemy.dialects.postgresql。全部其他arrexproperator=<内置函数 eq>


ARRAY 级 Comparator.all() 方法的同义词。有关详细信息,请参阅该方法。


sqlalchemy.dialects.postgresql。HStrea的


使用 PostgreSQL hstore() 函数在 SQL 表达式中构造 hstore 值。


hstore 函数接受一个或两个参数,如 PostgreSQL 文档中所述。


例如:

from sqlalchemy.dialects.postgresql import array, hstore

select(hstore("key1", "value1"))

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


另请参阅


HSTORE - PostgreSQL HSTORE 数据类型。


属性 sqlalchemy.dialects.postgresql.hstore. inherit_cache:boolNone = True


指示此 HasCacheKey 实例是否应使用其直接超类使用的缓存键生成方案。


该属性默认为 None,这表示构造尚未考虑是否适合参与缓存;这在功能上等效于将值设置为 False,但还会发出警告。


如果与对象对应的 SQL 不基于此类的本地属性而不是其超类而更改,则可以在特定类上将此标志设置为 True


另请参阅


启用对自定义构造的缓存支持 - 设置 HasCacheKey.inherit_cache 第三方或用户定义的 SQL 构造的属性。


属性 sqlalchemy.dialects.postgresql.hstore. 类型


HSTORE 的别名


sqlalchemy.dialects.postgresql。to_tsvector


PostgreSQL to_tsvector SQL 函数。


此函数应用 REGCONFIG 参数的自动强制转换以自动使用 REGCONFIG 数据类型,并应用 TSVECTOR 的返回类型。


假设已导入 PostgreSQL 方言,则通过调用 from sqlalchemy.dialects import postgresql ,或者通过使用 create_engine("postgresql...")to_tsvector 将在调用 sqlalchemy.func.to_tsvector() 中,确保在编译和执行时使用正确的参数和返回类型处理程序。


2.0.0rc1 版本的新Function。


类签名


sqlalchemy.dialects.postgresql.to_tsvector sqlalchemy.dialects.postgresql.ext._regconfig_fn


sqlalchemy.dialects.postgresql。to_tsquery


PostgreSQL to_tsquery SQL 函数。


此函数应用 REGCONFIG 参数的自动强制转换以自动使用 REGCONFIG 数据类型,并应用 TSQUERY 的返回类型。


假设已导入 PostgreSQL 方言,则通过调用 from sqlalchemy.dialects import postgresql ,或者通过使用 create_engine("postgresql...")to_tsquery 将在调用 sqlalchemy.func.to_tsquery()),确保在编译和执行时使用正确的参数和返回类型处理程序。


2.0.0rc1 版本的新Function。


类签名


sqlalchemy.dialects.postgresql.to_tsquery sqlalchemy.dialects.postgresql.ext._regconfig_fn


sqlalchemy.dialects.postgresql。plainto_tsquery


PostgreSQL plainto_tsquery SQL 函数。


此函数应用 REGCONFIG 参数的自动强制转换以自动使用 REGCONFIG 数据类型,并应用 TSQUERY 的返回类型。


假设已导入 PostgreSQL 方言,则通过调用 from sqlalchemy.dialects import postgresql ,或者通过使用 create_engine("postgresql...")plainto_tsquery sqlalchemy.func.plainto_tsquery() 将在 ininvoke 时自动使用,确保在编译和执行时使用正确的参数和返回类型处理程序。


2.0.0rc1 版本的新Function。


类签名


sqlalchemy.dialects.postgresql.plainto_tsquery sqlalchemy.dialects.postgresql.ext._regconfig_fn


sqlalchemy.dialects.postgresql。phraseto_tsquery


PostgreSQL phraseto_tsquery SQL 函数。


此函数应用 REGCONFIG 参数的自动强制转换以自动使用 REGCONFIG 数据类型,并应用 TSQUERY 的返回类型。


假设已导入 PostgreSQL 方言,则通过调用 from sqlalchemy.dialects import postgresql ,或者通过使用 create_engine("postgresql...")phraseto_tsquery 将在 invokeking sqlalchemy.func.phraseto_tsquery() 时自动使用,确保在编译和执行时使用正确的参数和返回类型处理程序。


2.0.0rc1 版本的新Function。


类签名


sqlalchemy.dialects.postgresql.phraseto_tsquery sqlalchemy.dialects.postgresql.ext._regconfig_fn


sqlalchemy.dialects.postgresql。websearch_to_tsquery


PostgreSQL websearch_to_tsquery SQL 函数。


此函数应用 REGCONFIG 参数的自动强制转换以自动使用 REGCONFIG 数据类型,并应用 TSQUERY 的返回类型。


假设已导入 PostgreSQL 方言,则通过调用 from sqlalchemy.dialects import postgresql ,或者通过使用 create_engine("postgresql...")websearch_to_tsquery 将在 invokeng sqlalchemy.func.websearch_to_tsquery() 时自动使用,确保在编译和执行时使用正确的参数和返回类型处理程序。


2.0.0rc1 版本的新Function。


类签名


sqlalchemy.dialects.postgresql.websearch_to_tsquery sqlalchemy.dialects.postgresql.ext._regconfig_fn


sqlalchemy.dialects.postgresql。ts_headline


PostgreSQL ts_headline SQL 函数。


此函数应用 REGCONFIG 参数的自动强制转换以自动使用 REGCONFIG 数据类型,并应用 TEXT 的返回类型。


假设已导入 PostgreSQL 方言,则通过调用 from sqlalchemy.dialects import postgresql ,或者通过使用 create_engine("postgresql...")ts_headline 将在调用 sqlalchemy.func.ts_headline()中,确保在编译和执行时使用正确的参数和返回类型处理程序。


2.0.0rc1 版本的新Function。


类签名


sqlalchemy.dialects.postgresql.ts_headline sqlalchemy.dialects.postgresql.ext._regconfig_fn


PostgreSQL 约束类型


SQLAlchemy 通过 ExcludeConstraint 类:


对象名称

描述

ExcludeConstraint


表级 EXCLUDE 约束。


sqlalchemy.dialects.postgresql。ExcludeConstraint (排除约束)¶


表级 EXCLUDE 约束。


定义 EXCLUDE 约束,如 PostgreSQL 中所述 文档


方法 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"},
    )
)


此示例中定义的 exclude 约束需要 btree_gist 扩展,可以使用命令 CREATE EXTENSION btree_gist; 创建。


参数

  • 元素


    由两个元组组成的序列,形式为 (column, operator),其中 “column” 是 Column 对象或 SQL 表达式元素(例如 func.int8range(table.from, table.to) )或列名(字符串),“operator”是包含要使用的运算符的字符串(例如 “&&”“=”)。


    为了在 Column object 不可用,同时确保 任何必要的引用规则生效,一个临时的 column() object 的 intent 请求。 该也可以是字符串 SQL 表达式(当作为 literal_column() 或 文本()


  • name— 可选,此约束的数据库内名称。


  • deferrable – 可选 bool。如果设置,则在为此约束发出 DDL 时发出 DEFERRABLE 或 NOT DEFERRABLE。


  • initially – 可选字符串。如果设置,则在为此约束发出 DDL 时发出 INITIALLY <value>。


  • using – 可选字符串。如果设置,则在为此约束发出 DDL 时发出 USING <index_method>。默认为 'gist'。


  • 其中


    可选的 SQL 表达式构造或文本 SQL 字符串。如果设置,则在为此约束发出 DDL 时发出 WHERE <predicate>。


    警告


    ExcludeConstraint ExcludeConstraint.where 参数可以作为 Python 字符串参数传递,该参数将被视为受信任的 SQL 文本并呈现为给定文本。不要将不受信任的输入传递给此参数



  • 可选字典。 用于定义 元素;的工作方式与 postgresql_ops 参数指定给 Index 构造。


    在 1.3.21 版本加入.


    另请参阅


    运算符类 - 如何指定 PostgreSQL 运算符类的一般说明。


例如:

from sqlalchemy.dialects.postgresql import ExcludeConstraint, TSRANGE


class RoomBooking(Base):
    __tablename__ = "room_booking"

    room = Column(Integer(), primary_key=True)
    during = Column(TSRANGE())

    __table_args__ = (ExcludeConstraint(("room", "="), ("during", "&&")),)


PostgreSQL DML 结构


对象名称

描述


insert(表)


构造特定于 PostgreSQL 的变体 Insert 构建。


插入


特定于 PostgreSQL 的 INSERT 实现。


函数 sqlalchemy.dialects.postgresql。inserttable _DMLTableArgument 插入


构造特定于 PostgreSQL 的变体 Insert 构建。


sqlalchemy.dialects.postgresql.insert() 函数创建一个 sqlalchemy.dialects.postgresql.Insert .此类基于与方言无关的 Insert 结构,该结构可以使用 SQLAlchemy Core 中的 insert() 函数构造。


Insert 构造包括其他方法 Insert.on_conflict_do_update() Insert.on_conflict_do_nothing()


sqlalchemy.dialects.postgresql。插入


特定于 PostgreSQL 的 INSERT 实现。


为特定于 PG 的语法添加方法,例如 ON CONFLICT。


Insert 对象是使用 sqlalchemy.dialects.postgresql.insert() 功能。


attribute excluded不包括属性 sqlalchemy.dialects.postgresql.Insert. )¶


为 ON CONFLICT 语句提供排除的命名空间


PG 的 ON CONFLICT 子句允许引用将要插入的行,称为 excluded。此属性提供此行中的所有列以供引用。


提示


Insert.excluded 属性是 ColumnCollection 的一个实例,它提供的接口与 Table.c 的接口相同 访问表和列中描述的集合。在这个集合中,普通名称可以像属性一样访问(例如 stmt.excluded.some_column),但特殊名称和字典方法名称应该使用索引访问来访问,例如 stmt.excluded[“column name”]stmt.excluded[“values”] 中。 请参阅 docsstring 的 ColumnCollection 获取更多示例。


另请参阅


插入。。。ON CONFLICT (Upsert) - 如何使用 Insert.excluded 的示例


属性 sqlalchemy.dialects.postgresql.Insert. inherit_cache:boolNone = False


指示此 HasCacheKey 实例是否应使用其直接超类使用的缓存键生成方案。


该属性默认为 None,这表示构造尚未考虑是否适合参与缓存;这在功能上等效于将值设置为 False,但还会发出警告。


如果与对象对应的 SQL 不基于此类的本地属性而不是其超类而更改,则可以在特定类上将此标志设置为 True


另请参阅


启用对自定义构造的缓存支持 - 设置 HasCacheKey.inherit_cache 第三方或用户定义的 SQL 构造的属性。


方法 sqlalchemy.dialects.postgresql.Insert. on_conflict_do_nothingconstraint:strColumnCollectionConstraintIndexNone=None, index_elements:Iterable[Column[Any]strDDLConstraintColumnRole]None=None, index_where:WhereHavingRoleNone=None) Self


为 ON CONFLICT 子句指定 DO NOTHING作。


constraintindex_elements 参数是可选的,但只能指定其中一个参数。


参数

  • constraint– 表上唯一或排除约束的名称,或者约束对象本身(如果它具有 .name 属性)。


  • index_elements– 由字符串 column names、Column 组成的序列 对象或将使用的其他列表达式对象 来推断目标索引。


  • index_where– 可用于推断条件目标索引的附加 WHERE 标准。


方法 sqlalchemy.dialects.postgresql.Insert. on_conflict_do_updateconstraint:strColumnCollectionConstraintIndexNone=None, index_elements:Iterable[Column[Any]strDDLConstraintColumnRole]None=None, index_where:WhereHavingRoleNone=None, set_:Mapping[Any,Any]ColumnCollection[Any,Any]None=None, 其中:WhereHavingRoleNone=None) Self


为 ON CONFLICT 子句指定 DO UPDATE SET作。


constraintindex_elements 参数是必需的,但只能指定其中一个参数。


参数

  • constraint– 表上唯一或排除约束的名称,或者约束对象本身(如果它具有 .name 属性)。


  • index_elements– 由字符串 column names、Column 组成的序列 对象或将使用的其他列表达式对象 来推断目标索引。


  • index_where– 可用于推断条件目标索引的附加 WHERE 标准。

  • set_


    一个字典或其他映射对象,其中键是目标表中的列名,或者是 Column 对象或与目标表匹配的其他 ORM 映射列,以及表达式或文本作为值,指定要执行的 SET作。


    1.4 版本中的新功能: Insert.on_conflict_do_update.set_ 参数支持来自目标的 Column 对象 作为键。


    警告


    此字典考虑 Python 指定的默认 UPDATE 值或生成函数,例如使用 Column.onupdate 指定的值。 对于 ON CONFLICT 样式 UPDATE,除非它们是在 Insert.on_conflict_do_update.set_ 字典。


  • where – 可选参数。表示 WHERE 的表达式对象 限制受 DO UPDATE SET 影响的行的子句。不满足 WHERE 条件的行将不会被更新(实际上是 对这些行执行任何)。

psycopg2


通过 psycopg2 驱动程序支持 PostgreSQL 数据库。


数据库接口


psycopg2 的文档和下载信息(如果适用)可在以下网址获得: https://pypi.org/project/psycopg2/


连接


连接字符串:

postgresql+psycopg2://user:password@host:port/dbname[?key=value&key=value...]


psycopg2 Connect 参数


特定于 SQLAlchemy psycopg2 方言的关键字参数可以传递给 create_engine(),包括以下内容:


提示


上面的关键字参数是 dialect 关键字参数,这意味着它们作为显式关键字参数传递给 create_engine()

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


这些参数不应与 DBAPI connect 参数混淆,后者作为 create_engine.connect_args 的一部分传递 dictionary 和/或 URL 查询字符串中传递,详见 自定义 DBAPI connect() 参数/连接例程部分。


SSL 连接


psycopg2 模块有一个名为 sslmode 的连接参数,用于 控制其有关安全 (SSL) 连接的行为。默认值为 sslmode=首选;它将尝试 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 域连接进行连接。当主机 部分,SQLAlchemy 将 None 传递给 psycopg2,它指定 Unix 域通信而不是 TCP/IP 通信:

create_engine("postgresql+psycopg2://user:password@/dbname")


默认情况下,使用的套接字文件用于连接到 /tmp 中的 Unix 域套接字,或构建 PostgreSQL 时指定的任何套接字目录。可以通过将路径名传递给 psycopg2 来覆盖此值,使用 host 作为额外的关键字参数:

create_engine(
    "postgresql+psycopg2://user:password@/dbname?host=/var/lib/postgresql"
)


警告


此处接受的格式允许主 URL 中除了 “host” 查询字符串参数外,还允许使用主机名。使用此 URL 时 格式,则初始主机将被静默忽略。即,此 URL:

engine = create_engine(
    "postgresql+psycopg2://user:password@myhost1/dbname?host=myhost2"
)


在上面,主机名 myhost1静默忽略并丢弃。连接的主机是 myhost2 主机。


这是为了保持与 PostgreSQL 自己的 URL 格式的某种程度的兼容性,该格式已经过测试,其行为方式相同,并且 PifPaf 等工具对两个主机名进行硬编码。


另请参阅

PQconnectdbParams


指定多个回退主机


psycopg2 支持连接字符串中的多个连接点。当 host 参数在 query 部分 URL 中,SQLAlchemy 将创建一个 host 和 port 的字符串 为建立连接而提供的信息。 代币可能包括 host::p orthost;在后一种情况下,libpq 选择默认端口。在下面的示例中,为 HostA::P ortA、连接到默认端口的 HostBHostC::P ortC 指定了三个主机连接:

create_engine(
    "postgresql+psycopg2://user:password@/dbname?host=HostA:PortA&host=HostB&host=HostC:PortC"
)


作为替代方案,也可以使用 libpq 查询字符串格式;这指定了 hostport 作为带有逗号分隔列表的单个查询字符串参数 - 可以通过在逗号分隔列表中指示空值来选择默认端口:

create_engine(
    "postgresql+psycopg2://user:password@/dbname?host=HostA,HostB,HostC&port=PortA,,PortC"
)


无论使用哪种 URL 样式,都会根据 configurable 策略,可以使用 libpq target_session_attrs 参数。根据 libpq,这默认为任何 这表示然后尝试连接到每个主机,直到连接成功。 其他策略包括 primaryprefer-standby 等。 完整的 list 由 PostgreSQL 记录在 libpq 连接字符串。


例如,要指示两个使用策略的主机:

create_engine(
    "postgresql+psycopg2://user:password@/dbname?host=HostA:PortA&host=HostB&host=HostC:PortC&target_session_attrs=primary"
)


在 1.4.40 版本发生变更: 修复了 psycopg2 多主机格式中的端口规范,以前在此上下文中无法正确解释端口。现在还支持 libpq 逗号分隔格式。


1.3.20 版本中的新功能: 在 PostgreSQL 连接字符串中支持多个主机。


另请参阅


libpq 连接字符串 - 请参阅 libpq 文档中的此部分,了解有关多主机支持的完整背景信息。


空 DSN 连接 / 环境变量连接


psycopg2 DBAPI 可以通过将空 DSN 传递给 libpq 客户端库来连接到 PostgreSQL,默认情况下,该库表示连接到为“信任”连接打开的 localhost PostgreSQL 数据库。可以使用一组特定的环境变量进一步定制此行为,这些变量以 PG_...为前缀,libpq 使用这些变量来代替连接字符串的任何或所有元素。


对于此表单,可以传递 URL,但可以不带初始方案以外的任何元素:

engine = create_engine("postgresql+psycopg2://")


在上面的形式中,一个空的 “dsn” 字符串被传递给 psycopg2.connect() 函数,该函数又表示传递给 libpq 的空 DSN。


1.3.2 新版功能: 支持 psycopg2 的无参数连接。


另请参阅


环境变量 - 有关如何使用 PG_ 的 PostgreSQL 文档 连接的环境变量。


每个语句/连接执行选项


Connection.execution_options() Executable.execution_options() Query.execution_options() 中,除了不特定于 DBAPI 的 DBAPI 之外:


  • isolation_level - 设置 Connection 生命周期的事务隔离级别(只能在 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 语句的 “Insert Many Values” Behavior (插入多个值)


2.0 版本中的新功能: 取代了 psycopg2 的 execute_values() 快速执行 帮助程序具有称为 insertmany值


psycopg2 方言保留了使用 psycopg2 特定的 execute_batch() 功能,尽管预计这并不是一种广泛的 used 功能。 可以使用 executemany_mode可以传递给 create_engine() 的标志:

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


executemany_mode 的可能选项包括:


  • values_only - 这是默认值。 SQLAlchemy 的原生 insertmanyValues 处理程序用于限定 INSERT 语句(假设 create_engine.use_insertmanyvalues 保留其默认值 True。此处理程序重写简单的 INSERT 语句以包含多个 VALUES 子句,以便可以使用一个语句插入多个参数集。


  • 'values_plus_batch'- SQLAlchemy 的原生 insertmanyValues 处理程序用于限定 INSERT 语句(假设 create_engine.use_insertmanyvalues 保留其默认值 True。然后,psycopg2 的 execute_batch() 处理程序用于在使用多个参数集执行时限定 UPDATE 和 DELETE 语句。使用此模式时,CursorResult.rowcount 属性不包含针对 UPDATE 和 DELETE 语句。


在 2.0 版更改: 从 psycopg2 executemany_mode中删除了 'batch''None' 选项。 控制 INSERT 的批处理 语句现在通过 create_engine.use_insertmanyvalues engine-level 参数。


术语“限定语句”是指正在执行的语句是核心 insert()update()delete() 结构,而不是纯文本 SQL 字符串或使用 text() 构造的字符串。它也不能是一个特殊的 “extension” 语句,例如 “ON CONFLICT” 的 “upsert” 语句。使用 ORM 时,ORM flush 进程使用的所有 insert/update/delete 语句都是合格的。


psycopg2 “batch” 策略的 “page size” 可能会受到使用 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”的背景


发送多个参数 - 有关使用 连接 object 执行语句,使 使用 DBAPI .executemany() 方法。


Unicode 与 Psycopg2


psycopg2 DBAPI 驱动程序以透明方式支持 Unicode 数据。


可以通过以下方式控制 psycopg2 方言的客户端字符编码:


  • 对于 PostgreSQL 9.1 及更高版本,client_encoding 参数可能是 传入数据库 URL;此参数由底层 libpqPostgreSQL 客户端库:

    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 都支持客户端编码 值,该值将在 Database Connections 首次 既定。 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 数据库设置 Client 端编码的一种常见方法是确保在服务器端 postgresql.conf 文件中对其进行配置;这是为所有数据库中始终为一种编码的服务器设置编码的推荐方法:

    # postgresql.conf file
    
    # client_encoding = sql_ascii # actually, defaults to database
    # encoding
    client_encoding = utf8


交易


psycopg2 dialect 完全支持 SAVEPOINT 和两阶段提交作。


Psycopg2 交易隔离级别


事务隔离级别中所述,所有 PostgreSQL 方言都支持通过传递给 create_engine()isolation_level 参数来设置事务隔离级别 , 以及 isolation_level 使用的 Connection.execution_options() 。当使用 psycopg2 dialect 时,这些选项使用 psycopg2 的 set_isolation_level() 连接方法,而不是发出 PostgreSQL 指令;这是因为 psycopg2 的 API 级设置在任何情况下总是在每笔交易开始时发出。


psycopg2 方言支持隔离级别的这些常数:


  • 读取已提交


  • 读取 UNCOMMITTED


  • 可重复读取


  • 序列 化


  • 自动提交


NOTICE 日志记录


psycopg2 方言将通过 sqlalchemy.dialects.postgresql Logger 记录 PostgreSQL NOTICE 消息。当此 Logger 设置为 logging.INFO 级别时,将记录通知消息:

import logging

logging.getLogger("sqlalchemy.dialects.postgresql").setLevel(logging.INFO)


上面,假设 logging 是在外部配置的。如果不是这种情况,则必须使用诸如 logging.basicConfig() 之类的配置:

import logging

logging.basicConfig()  # log messages to stdout
logging.getLogger("sqlalchemy.dialects.postgresql").setLevel(logging.INFO)


另请参阅


记录 HOWTO - 在 python.org 网站上


HSTORE 类型


psycopg2 DBAPI 包括一个扩展,用于本机处理 HSTORE 类型的封送处理。当使用 psycopg2 版本 2.4 或更高版本时,SQLAlchemy psycopg2 方言将默认启用此扩展,并且检测到目标数据库已设置使用 HSTORE 类型。换句话说,当方言建立第一个连接时,将执行如下序列:


  1. 使用请求可用的 HSTORE oid psycopg2.extras.HstoreAdapter.get_oids() 。如果此函数返回 HSTORE 标识符列表,则我们确定 HSTORE 扩展存在。如果安装的 psycopg2 版本低于 2.4 版,则跳过此函数。


  2. 如果 use_native_hstore 标志的默认值为 True,并且我们检测到 HSTORE oid 可用,则 psycopg2.extensions.register_hstore() extension 为所有连接调用。


register_hstore() 扩展具有所有 Python 无论目标类型如何,都接受作为参数的词典 列。此扩展将字典转换为文本 HSTORE 表达式。如果不需要此行为,请通过将 use_native_hstore 设置为 False 来禁用 hstore 扩展,如下所示:

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


psycopg2.extensions.register_hstore() 未使用 extension。这仅仅意味着 Python 字典和 HSTORE 字符串格式之间的强制转换,无论是在参数端还是结果端,都将发生在 SQLAlchemy 自己的编组逻辑中,而不是 psycopg2 的编组逻辑中 这可能性能更高。


psycopg (心理控制) ¶


通过 psycopg(又名 psycopg 3)驱动程序支持 PostgreSQL 数据库。


数据库接口


有关psycopg(又名psycopg 3)的文档和下载信息(如适用),请访问: https://pypi.org/project/psycopg/


连接


连接字符串:

postgresql+psycopg://user:password@host:port/dbname[?key=value&key=value...]


psycopgpsycopg 版本 3 的包和模块名称 数据库驱动程序,以前称为 psycopg2。这个驱动程序与其前身 psycopg2 有很大的不同,以至于 SQLAlchemy 通过完全独立的方言来支持它;只要该包继续在现代 Python 版本中运行,对 psycopg2 的支持就会一直存在,并且仍然是 postgresql:// dialect 系列的默认方言。


SQLAlchemy psycopg 方言在相同的方言名称下提供同步和异步实现。根据引擎的创建方式选择正确的版本:


  • 使用 postgresql+psycopg://... 调用 create_engine() 将自动选择同步版本,例如:

    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 Dialect 与 Psycopg2 方言的大部分行为相同。更多文档可在此处找到。


使用不同的 Cursor 类


psycopg 和旧的 psycopg2 之间的区别之一 是绑定参数的处理方式:psycopg2 会在客户端绑定它们,而 psycopg 默认会在服务器端绑定它们。


通过在创建引擎时将 cursor_factory指定为 ClientCursor,可以将 psycopg 配置为执行客户端绑定:

from psycopg import ClientCursor

client_side_engine = create_engine(
    "postgresql+psycopg://...",
    connect_args={"cursor_factory": ClientCursor},
)


同样,当使用异步引擎时,可以指定 AsyncClientCursor

from psycopg import AsyncClientCursor

client_side_engine = create_async_engine(
    "postgresql+psycopg://...",
    connect_args={"cursor_factory": AsyncClientCursor},
)


另请参阅


客户端绑定游标

pg8000


通过 pg8000 驱动程序支持 PostgreSQL 数据库。


数据库接口


pg8000 的文档和下载信息(如果适用)可从以下网址获得: https://pypi.org/project/pg8000/


连接


连接字符串:

postgresql+pg8000://user:password@host:port/dbname[?key=value&key=value...]


在 1.4 版本发生变更: pg8000 dialect 已针对版本 1.16.6 及更高版本进行了更新,并且再次成为 SQLAlchemy 持续集成的一部分,具有完整的功能支持。


Unicode 代码¶


pg8000 将使用 PostgreSQL client_encoding 参数对它与服务器之间的字符串值进行编码/解码;默认情况下,这是 postgresql.conf 文件中的值,通常默认为 SQL_ASCII。通常,这可以更改为 utf-8,作为更有用的默认值:

# client_encoding = sql_ascii # actually, defaults to database encoding
client_encoding = utf8


可以通过执行 SQL 来覆盖会话的 client_encoding

SET CLIENT_ENCODING TO 'utf8';


SQLAlchemy 将根据使用 client_encoding 参数传递给 create_engine() 的值在所有新连接上执行此 SQL:

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 方言相同的隔离级别设置:


  • 读取已提交


  • 读取 UNCOMMITTED


  • 可重复读取


  • 序列 化


  • 自动提交


asyncPG


通过 asyncpg 驱动程序支持 PostgreSQL 数据库。


数据库接口


asyncpg 的文档和下载信息(如果适用)可在以下位置获得: https://magicstack.github.io/asyncpg/


连接


连接字符串:

postgresql+asyncpg://user:password@host:port/dbname[?key=value&key=value...]


asyncpg 方言是 SQLAlchemy 的第一个 Python asyncio 方言。


使用特殊的 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"
)


在 1.4 版本加入.


注意


默认情况下, asyncpg 不会解码 jsonjsonb 类型,而是将它们作为字符串返回。SQLAlchemy 为 json 设置默认类型解码器 以及使用 Python 内置 json.loads 函数的 jsonb 类型。 使用的 json 实现可以通过设置属性 json_deserializer 使用 create_engine()create_async_engine() 来获取。


多主机连接


asyncpg 方言支持多个回退主机,其方式与 psycopg2 和 psycopg 方言相同。语法相同,使用 host=<host>:<port> 组合作为附加查询字符串参数;但是,没有默认端口,因此所有主机都必须存在完整的端口号,否则会引发异常:

engine = create_async_engine(
    "postgresql+asyncpg://user:password@/dbname?host=HostA:5432&host=HostB:5432&host=HostC:5432"
)


有关此语法的完整背景信息,请参阅指定多个回退主机


2.0.18 新版功能.


准备好的语句缓存


asyncpg SQLAlchemy 方言使用 asyncpg.connection.prepare() for all 语句。 准备好的语句对象在 结构,该结构似乎为 statement 调用。 缓存基于每个 DBAPI 连接,这 表示准备好的语句的主存储位于 DBAPI 中 连接池中的池连接。 此缓存的大小 默认为每个 DBAPI 连接 100 个语句,可以使用 prepared_statement_cache_sizeDBAPI 参数(请注意,虽然此参数由 SQLAlchemy 实现,但它是 asyncpg 方言的 DBAPI 仿真部分的一部分,因此作为 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 版本中的新功能: 添加了 asyncpg 的 prepared_statement_cache_size


警告


asyncpg 数据库驱动程序必须使用 PostgreSQL 类型 OID 的缓存,当通过 DDL作更改自定义 PostgreSQL 数据类型(如 ENUM 对象)时,这些 OID 会过时。此外,当 DDL 被发送到 PostgreSQL 数据库时,如上所述由 SQLAlchemy 的驱动程序选择性缓存的准备好的语句本身也可能变得“过时”,该数据库修改了特定准备好的语句中涉及的表或其他对象。


SQLAlchemy asyncpg 方言将使其本地 process 在本地 连接,但这只能在单个 Python 进程中控制 / 数据库引擎。 如果从其他数据库引擎进行了 DDL 更改 和/或进程,正在运行的应用程序可能会遇到 AsyncPG 异常 InvalidCachedStatementError 和/或 InternalServerError("cache lookup failed for type <oid>") 它是否引用对先前结构进行作的池化数据库连接。当驱动程序通过清除其内部缓存以及 asyncpg 驱动程序的内部缓存来响应这些异常时,SQLAlchemy asyncpg 方言将从这些错误案例中恢复,但如果缓存的准备好的语句或 asyncpg 类型缓存已过时,则无法首先阻止它们被引发。 它也不能重试该语句,因为当这些错误发生时, PostgreSQL 事务将失效。


使用 PGBouncer 的准备好的语句名称


默认情况下,asyncpg 按数字顺序枚举准备好的语句,如果已为另一个准备好的语句使用名称,这可能会导致错误。如果您的应用程序使用 PgBouncer 等数据库代理来处理连接,则可能会出现此问题。一种可能的解决方法是使用动态准备好的语句名称,asyncpg 现在通过语句名称的可选 name 值来支持该名称。这允许您生成自己的唯一名称,这些名称不会与现有名称冲突。为此,您可以提供一个函数,每次准备准备好的语句时都会调用该函数:

from uuid import uuid4

engine = create_async_engine(
    "postgresql+asyncpg://user:pass@somepgbouncer/dbname",
    poolclass=NullPool,
    connect_args={
        "prepared_statement_name_func": lambda: f"__asyncpg_{uuid4()}__",
    },
)


警告


使用 PGBouncer 时,为了防止应用程序中堆积无用的准备好的语句,请务必使用 NullPool 池类,并将 PgBouncer 配置为使用 DISCARD 返回连接时。 DISCARD 命令用于释放 db 连接持有的资源, 包括准备好的语句。如果没有适当的设置,准备好的语句可以 快速累积并导致性能问题。


禁用 PostgreSQL JIT 以改进 ENUM 数据类型处理


Asyncpg 在使用 PostgreSQL ENUM 数据类型时存在问题,即在创建新的数据库连接时,可能会发出昂贵的查询,以便检索有关自定义类型的元数据,这已被证明会对性能产生负面影响。为了缓解此问题,可以使用传递给 create_async_engine() 的此设置从客户端禁用 PostgreSQL“jit”设置:

engine = create_async_engine(
    "postgresql+asyncpg://user:password@localhost/tmp",
    connect_args={"server_settings": {"jit": "off"}},
)


psycopg2cffi 文件¶


通过 psycopg2cffi 驱动程序支持 PostgreSQL 数据库。


数据库接口


psycopg2cffi 的文档和下载信息(如果适用)可在以下网址获得: https://pypi.org/project/psycopg2cffi/


连接


连接字符串:

postgresql+psycopg2cffi://user:password@host:port/dbname[?key=value&key=value...]


psycopg2cffipsycopg2 的改编版,使用 CFFI 作为 C 层。这使得它适合在 PyPy 等中使用。文档符合 psycopg2