SQLAlchemy 2.0 文档
方言
- PostgreSQL¶
- 支持 PostgreSQL 数据库。
- 序列/SERIAL/IDENTITY
- 服务器端游标
- 事务隔离级别
- 设置 READ ONLY / DEFERRABLE
- 临时表 / 连接池的资源重置
- 在连接时设置备用搜索路径
- 远程模式表内省和 PostgreSQL search_path
- INSERT/UPDATE…RETURNING
- INSERT…ON CONFLICT (Upsert)
- 全文搜索
- FROM ONLY …
- PostgreSQL 特定的索引选项
- PostgreSQL 索引反射
- 特殊反射选项
- PostgreSQL 表选项
- PostgreSQL 约束选项
- 表值、表和列值函数、行和元组对象
- ARRAY 类型
- JSON 类型
- HSTORE 类型
- ENUM 类型
- 范围和多范围类型
范围
Range.__eq__()
Range.adjacent_to()
Range.contained_by()
Range.contains()
Range.difference()
Range.intersection()
Range.is_empty
Range.isempty
Range.lower
Range.lower_inc
Range.lower_inf
Range.not_extend_left_of()
Range.not_extend_right_of()
Range.overlaps()
Range.strictly_left_of()
Range.strictly_right_of()
Range.union()
Range.upper
Range.upper_inc
Range.upper_inf
- 多范围
- 网络数据类型
- PostgreSQL 数据类型
AbstractRange
AbstractRange.comparator_factory
AbstractRange.comparator_factory.adjacent_to()
AbstractRange.comparator_factory.contained_by()
AbstractRange.comparator_factory.contains()
AbstractRange.comparator_factory.difference()
AbstractRange.comparator_factory.intersection()
AbstractRange.comparator_factory.not_extend_left_of()
AbstractRange.comparator_factory.not_extend_right_of()
AbstractRange.comparator_factory.overlaps()
AbstractRange.comparator_factory.strictly_left_of()
AbstractRange.comparator_factory.strictly_right_of()
AbstractRange.comparator_factory.union()
AbstractSingleRange
AbstractMultiRange
ARRAY
BIT
BYTEA
CIDR
CITEXT
DOMAIN
ENUM
HSTORE
HSTORE.Comparator
HSTORE.Comparator.array()
HSTORE.Comparator.contained_by()
HSTORE.Comparator.contains()
HSTORE.Comparator.defined()
HSTORE.Comparator.delete()
HSTORE.Comparator.has_all()
HSTORE.Comparator.has_any()
HSTORE.Comparator.has_key()
HSTORE.Comparator.keys()
HSTORE.Comparator.matrix()
HSTORE.Comparator.slice()
HSTORE.Comparator.vals()
HSTORE.__init__()
HSTORE.bind_processor()
HSTORE.comparator_factory
HSTORE.hashable
HSTORE.result_processor()
INET
INTERVAL
JSON
JSONB
JSONPATH
MACADDR
MACADDR8
MONEY
OID
REGCONFIG
REGCLASS
TIMESTAMP
TIME
TSQUERY
TSVECTOR
INT4RANGE
INT8RANGE
NUMRANGE
DATERANGE
TSRANGE
TSTZRANGE
INT4MULTIRANGE
INT8MULTIRANGE
NUMMULTIRANGE
DATEMULTIRANGE
TSMULTIRANGE
TSTZMULTIRANGE
MultiRange
- PostgreSQL SQL 元素和函数
- PostgreSQL 约束类型
- PostgreSQL DML 构造
- psycopg2
- psycopg
- pg8000
- asyncpg
- psycopg2cffi
- MySQL 和 MariaDB
- SQLite
- Oracle
- Microsoft SQL Server
项目版本
- 上一页: 方言
- 下一页: MySQL 和 MariaDB
- 上一级: 首页
- 本页内容
- PostgreSQL
- 支持 PostgreSQL 数据库。
- 序列/SERIAL/IDENTITY
- 服务器端游标
- 事务隔离级别
- 设置 READ ONLY / DEFERRABLE
- 临时表 / 连接池的资源重置
- 在连接时设置备用搜索路径
- 远程模式表内省和 PostgreSQL search_path
- INSERT/UPDATE…RETURNING
- INSERT…ON CONFLICT (Upsert)
- 全文搜索
- FROM ONLY …
- PostgreSQL 特定的索引选项
- PostgreSQL 索引反射
- 特殊反射选项
- PostgreSQL 表选项
- PostgreSQL 约束选项
- 表值、表和列值函数、行和元组对象
- ARRAY 类型
- JSON 类型
- HSTORE 类型
- ENUM 类型
- 范围和多范围类型
范围
Range.__eq__()
Range.adjacent_to()
Range.contained_by()
Range.contains()
Range.difference()
Range.intersection()
Range.is_empty
Range.isempty
Range.lower
Range.lower_inc
Range.lower_inf
Range.not_extend_left_of()
Range.not_extend_right_of()
Range.overlaps()
Range.strictly_left_of()
Range.strictly_right_of()
Range.union()
Range.upper
Range.upper_inc
Range.upper_inf
- 多范围
- 网络数据类型
- PostgreSQL 数据类型
AbstractRange
AbstractRange.comparator_factory
AbstractRange.comparator_factory.adjacent_to()
AbstractRange.comparator_factory.contained_by()
AbstractRange.comparator_factory.contains()
AbstractRange.comparator_factory.difference()
AbstractRange.comparator_factory.intersection()
AbstractRange.comparator_factory.not_extend_left_of()
AbstractRange.comparator_factory.not_extend_right_of()
AbstractRange.comparator_factory.overlaps()
AbstractRange.comparator_factory.strictly_left_of()
AbstractRange.comparator_factory.strictly_right_of()
AbstractRange.comparator_factory.union()
AbstractSingleRange
AbstractMultiRange
ARRAY
BIT
BYTEA
CIDR
CITEXT
DOMAIN
ENUM
HSTORE
HSTORE.Comparator
HSTORE.Comparator.array()
HSTORE.Comparator.contained_by()
HSTORE.Comparator.contains()
HSTORE.Comparator.defined()
HSTORE.Comparator.delete()
HSTORE.Comparator.has_all()
HSTORE.Comparator.has_any()
HSTORE.Comparator.has_key()
HSTORE.Comparator.keys()
HSTORE.Comparator.matrix()
HSTORE.Comparator.slice()
HSTORE.Comparator.vals()
HSTORE.__init__()
HSTORE.bind_processor()
HSTORE.comparator_factory
HSTORE.hashable
HSTORE.result_processor()
INET
INTERVAL
JSON
JSONB
JSONPATH
MACADDR
MACADDR8
MONEY
OID
REGCONFIG
REGCLASS
TIMESTAMP
TIME
TSQUERY
TSVECTOR
INT4RANGE
INT8RANGE
NUMRANGE
DATERANGE
TSRANGE
TSTZRANGE
INT4MULTIRANGE
INT8MULTIRANGE
NUMMULTIRANGE
DATEMULTIRANGE
TSMULTIRANGE
TSTZMULTIRANGE
MultiRange
- PostgreSQL SQL 元素和函数
- PostgreSQL 约束类型
- PostgreSQL DML 构造
- psycopg2
- psycopg
- pg8000
- asyncpg
- psycopg2cffi
PostgreSQL¶
支持 PostgreSQL 数据库。
下表总结了当前数据库发布版本的支持级别。
支持类型 |
版本 |
---|---|
9.6+ |
|
9+ |
DBAPI 支持¶
以下方言/DBAPI 选项可用。请参阅各个 DBAPI 部分以获取连接信息。
序列/SERIAL/IDENTITY¶
PostgreSQL 支持序列,SQLAlchemy 使用序列作为为基于整数的主键列创建新主键值的默认方法。创建表时,SQLAlchemy 将为基于整数的主键列发出 SERIAL
数据类型,这将生成与该列对应的序列和服务器端默认值。
要指定用于主键生成的特定命名序列,请使用 Sequence()
构造
Table(
"sometable",
metadata,
Column(
"id", Integer, Sequence("some_id_seq", start=1), primary_key=True
),
)
当 SQLAlchemy 发出单个 INSERT 语句时,为了满足“最后插入标识符”可用的约定,RETURNING 子句被添加到 INSERT 语句中,该子句指定应在语句完成后返回主键列。RETURNING 功能仅在使用 PostgreSQL 8.2 或更高版本时才生效。作为回退方法,序列(无论是显式指定还是通过 SERIAL
隐式指定)都会预先独立执行,返回的值将用于后续插入。请注意,当使用 “executemany” 语义执行 insert()
构造时,“最后插入标识符” 功能不适用;在这种情况下,既不会发出 RETURNING 子句,也不会预先执行序列。
PostgreSQL 10 及更高版本的 IDENTITY 列¶
PostgreSQL 10 及更高版本具有取代 SERIAL 使用的新 IDENTITY 功能。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)
)
注意
以前版本的 SQLAlchemy 没有内置对 IDENTITY 渲染的支持,并且可以使用以下编译钩子来替换 SERIAL 的出现
from sqlalchemy.schema import CreateColumn
from sqlalchemy.ext.compiler import compiles
@compiles(CreateColumn, "postgresql")
def use_identity(element, compiler, **kw):
text = compiler.visit_create_column(element, **kw)
text = text.replace("SERIAL", "INT GENERATED BY DEFAULT AS IDENTITY")
return text
使用上述方法,如下表所示
t = Table(
"t", m, Column("id", Integer, primary_key=True), Column("data", String)
)
将在后端数据库上生成为
CREATE TABLE t (
id INT GENERATED BY DEFAULT AS IDENTITY,
data VARCHAR,
PRIMARY KEY (id)
)
服务器端游标¶
psycopg2、asyncpg 方言支持服务器端游标,其他方言也可能支持。
通过使用 Connection.execution_options.stream_results
连接执行选项,可以在每个语句的基础上启用服务器端游标
with engine.connect() as conn:
result = conn.execution_options(stream_results=True).execute(
text("select * from table")
)
请注意,某些类型的 SQL 语句可能不支持服务器端游标;通常,只有返回行的 SQL 语句才应与此选项一起使用。
版本 1.4 中已弃用: 方言级别的 server_side_cursors 标志已弃用,将在未来版本中删除。请使用 Connection.stream_results
执行选项以获得非缓冲游标支持。
另请参阅
事务隔离级别¶
大多数 SQLAlchemy 方言都支持使用 create_engine.isolation_level
参数在 create_engine()
级别以及在 Connection
级别通过 Connection.execution_options.isolation_level
参数设置事务隔离级别。
对于 PostgreSQL 方言,此功能通过使用 DBAPI 特定的功能来实现,例如 psycopg2 的隔离级别标志,它会将隔离级别设置嵌入到 "BEGIN"
语句中,或者对于没有直接支持的 DBAPI,通过在 DBAPI 发出的 "BEGIN"
语句之前发出 SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL <level>
。对于特殊的 AUTOCOMMIT 隔离级别,使用 DBAPI 特定的技术,这通常是 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
还有更多用于隔离级别配置的选项,例如链接到主 Engine
的 “子引擎” 对象,每个对象都应用不同的隔离级别设置。有关背景信息,请参阅 设置事务隔离级别,包括 DBAPI 自动提交 中的讨论。
大多数 PostgreSQL 方言上的 isolation_level
的有效值包括
READ COMMITTED
READ UNCOMMITTED
REPEATABLE READ
SERIALIZABLE
AUTOCOMMIT
设置 READ ONLY / DEFERRABLE¶
大多数 PostgreSQL 方言都支持设置事务的 “READ ONLY” 和 “DEFERRABLE” 特性,这是对隔离级别设置的补充。这两个属性可以与隔离级别结合或独立建立,方法是将 postgresql_readonly
和 postgresql_deferrable
标志与 Connection.execution_options()
一起传递。下面的示例说明了同时传递 "SERIALIZABLE"
隔离级别以及设置 “READ ONLY” 和 “DEFERRABLE”
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
执行选项的支持。
临时表 / 连接池的资源重置¶
SQLAlchemy Engine
对象使用的 QueuePool
连接池实现包括 返回时重置 行为,当连接返回到池时,它将调用 DBAPI .rollback()
方法。虽然此回滚将清除先前事务使用的直接状态,但它不涵盖更广泛的会话级别状态,包括临时表以及其他服务器状态,例如预处理语句句柄和语句缓存。PostgreSQL 数据库包含各种可用于重置此状态的命令,包括 DISCARD
、RESET
、DEALLOCATE
和 UNLISTEN
。
要安装这些命令中的一个或多个作为执行返回时重置的方式,可以使用 PoolEvents.reset()
事件钩子,如下例所示。该实现将结束正在进行的事务,并使用 CLOSE
、RESET
和 DISCARD
命令丢弃临时表;有关每个语句作用的背景信息,请参阅 PostgreSQL 文档。
create_engine.pool_reset_on_return
参数设置为 None
,以便自定义方案可以完全替换默认行为。自定义钩子实现无论如何都会调用 .rollback()
,因为通常重要的是 DBAPI 自身对提交/回滚的跟踪将与事务状态保持一致
from sqlalchemy import create_engine
from sqlalchemy import event
postgresql_engine = create_engine(
"postgresql+pyscopg2://scott:tiger@hostname/dbname",
# disable default reset-on-return scheme
pool_reset_on_return=None,
)
@event.listens_for(postgresql_engine, "reset")
def _reset_postgresql(dbapi_connection, connection_record, reset_state):
if not reset_state.terminate_only:
dbapi_connection.execute("CLOSE ALL")
dbapi_connection.execute("RESET ALL")
dbapi_connection.execute("DISCARD TEMP")
# so that the DBAPI itself knows that the connection has been
# reset
dbapi_connection.rollback()
在版本 2.0.0b3 中更改: 向 PoolEvents.reset()
事件添加了额外的状态参数,并额外确保为所有 “重置” 事件调用该事件,使其适合作为自定义 “重置” 处理程序的位置。使用 PoolEvents.checkin()
处理程序的先前方案仍然可用。
在连接时设置备用搜索路径¶
PostgreSQL search_path
变量指的是在 SQL 语句中引用特定表或其他对象时将隐式引用的模式名称列表。如下节 远程模式表内省和 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 连接回滚时,它不会被还原。
另请参阅
为新连接设置默认模式 - 在 使用 MetaData 描述数据库 文档中
远程模式表内省和 PostgreSQL search_path¶
最佳实践总结部分
将 search_path
变量保持为其默认值 public
,没有任何其他模式名称。确保用于连接的用户名 不 匹配远程模式,或确保从 search_path
中 删除 "$user"
令牌。对于其他模式名称,请在 Table
定义中显式命名它们。或者,postgresql_ignore_search_path
选项将导致所有反射的 Table
对象都设置 Table.schema
属性。
PostgreSQL 方言可以从任何模式反射表,如 从其他模式反射表 中所述。
在所有情况下,SQLAlchemy 在反射表时做的第一件事是 确定当前数据库连接的默认模式。它使用 PostgreSQL current_schema()
函数来执行此操作,如下所示,使用 PostgreSQL 客户端会话(即使用 psql
工具)
test=> select current_schema();
current_schema
----------------
public
(1 row)
上面我们看到,在 PostgreSQL 的普通安装中,默认模式名称是名称 public
。
但是,如果您的数据库用户名 与模式名称匹配,则 PostgreSQL 的默认行为是 使用该名称作为默认模式。下面,我们使用用户名 scott
登录。当我们创建一个名为 scott
的模式时,它会隐式更改默认模式
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
对象通过外键约束引用的表,必须决定如何在这些远程表中表示 .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)
上面,我们创建了一个表 referred
作为远程模式 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()
的返回值来确定远程模式名称。也就是说,如果我们的 search_path
设置为包含 test_schema
,并且我们按如下方式调用表反射过程
>>> from sqlalchemy import Table, MetaData, create_engine, text
>>> engine = create_engine("postgresql+psycopg2://scott:tiger@localhost/test")
>>> with engine.connect() as conn:
... conn.execute(text("SET search_path TO test_schema, public"))
... metadata_obj = MetaData()
... referring = Table("referring", metadata_obj, autoload_with=conn)
<sqlalchemy.engine.result.CursorResult object at 0x101612ed0>
上面的过程会将 referred
表传递到 MetaData.tables
集合中,该表在命名时 没有 模式
>>> metadata_obj.tables["referred"].schema is None
True
要更改反射的行为,以便无论 search_path
设置如何都保持引用的模式,请使用 postgresql_ignore_search_path
选项,该选项可以指定为 Table
和 MetaData.reflect()
的方言特定参数
>>> with engine.connect() as conn:
... conn.execute(text("SET search_path TO test_schema, public"))
... metadata_obj = MetaData()
... referring = Table(
... "referring",
... metadata_obj,
... autoload_with=conn,
... postgresql_ignore_search_path=True,
... )
<sqlalchemy.engine.result.CursorResult object at 0x1016126d0>
现在,我们将 test_schema.referred
存储为模式限定的
>>> metadata_obj.tables["test_schema.referred"].schema
'test_schema'
INSERT/UPDATE…RETURNING¶
该方言支持 PG 8.2 的 INSERT..RETURNING
、UPDATE..RETURNING
和 DELETE..RETURNING
语法。INSERT..RETURNING
默认用于单行 INSERT 语句,以便获取新生成的主键标识符。要指定显式的 RETURNING
子句,请在每个语句的基础上使用 _UpdateBase.returning()
方法
# INSERT..RETURNING
result = (
table.insert().returning(table.c.col1, table.c.col2).values(name="foo")
)
print(result.fetchall())
# UPDATE..RETURNING
result = (
table.update()
.returning(table.c.col1, table.c.col2)
.where(table.c.name == "foo")
.values(name="bar")
)
print(result.fetchall())
# DELETE..RETURNING
result = (
table.delete()
.returning(table.c.col1, table.c.col2)
.where(table.c.name == "foo")
)
print(result.fetchall())
INSERT…ON CONFLICT (Upsert)¶
从 9.5 版本开始,PostgreSQL 允许通过 INSERT
语句的 ON CONFLICT
子句将行“upsert”(更新或插入)到表中。只有当候选行不违反任何唯一约束时,才会插入该行。如果发生唯一约束冲突,则可以执行辅助操作,可以是 “DO UPDATE”,表示应更新目标行中的数据,也可以是 “DO NOTHING”,表示静默跳过此行。
冲突是使用现有的唯一约束和索引来确定的。这些约束可以使用 DDL 中声明的名称来识别,也可以通过声明构成索引的列和条件来推断。
SQLAlchemy 通过 PostgreSQL 特定的 insert()
函数提供 ON CONFLICT
支持,该函数提供了生成方法 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
另请参阅
INSERT .. ON CONFLICT - 在 PostgreSQL 文档中。
指定目标¶
这两种方法都使用命名约束或列推断来提供冲突的“目标”
Insert.on_conflict_do_update.index_elements
参数指定一个序列,其中包含字符串列名、Column
对象和/或 SQL 表达式元素,这些元素将标识唯一索引>>> do_update_stmt = insert_stmt.on_conflict_do_update( ... index_elements=["id"], set_=dict(data="updated value") ... ) >>> print(do_update_stmt)
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当使用
Insert.on_conflict_do_update.index_elements
推断索引时,还可以通过指定使用Insert.on_conflict_do_update.index_where
参数来推断部分索引>>> stmt = insert(my_table).values(user_email="a@b.com", data="inserted data") >>> stmt = stmt.on_conflict_do_update( ... index_elements=[my_table.c.user_email], ... index_where=my_table.c.user_email.like("%@gmail.com"), ... set_=dict(data=stmt.excluded.data), ... ) >>> print(stmt)
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.dataInsert.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)sInsert.on_conflict_do_update.constraint
参数也可以引用代表约束的 SQLAlchemy 构造,例如UniqueConstraint
、PrimaryKeyConstraint
、Index
或ExcludeConstraint
。在这种用法中,如果约束具有名称,则直接使用该名称。否则,如果约束未命名,则将使用推断,其中约束的表达式和可选的 WHERE 子句将在构造中拼写出来。此用法尤其方便引用Table
的命名或未命名主键,使用Table.primary_key
属性>>> do_update_stmt = insert_stmt.on_conflict_do_update( ... constraint=my_table.primary_key, set_=dict(data="updated value") ... ) >>> print(do_update_stmt)
INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s) ON CONFLICT (id) DO UPDATE SET data = %(param_1)s
SET 子句¶
ON CONFLICT...DO UPDATE
用于执行对已存在行的更新,使用新值以及来自提议插入的值的任意组合。这些值使用 Insert.on_conflict_do_update.set_
参数指定。此参数接受一个字典,其中包含 UPDATE 的直接值
>>> stmt = insert(my_table).values(id="some_id", data="inserted value")
>>> do_update_stmt = stmt.on_conflict_do_update(
... index_elements=["id"], set_=dict(data="updated value")
... )
>>> print(do_update_stmt)
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
指定的那些。除非在 Insert.on_conflict_do_update.set_
字典中手动指定这些值,否则不会为 ON CONFLICT 样式的 UPDATE 执行这些值。
使用排除的 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
参数的 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
完全跳过插入行;下面使用 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 的全文搜索系统可通过使用 func
命名空间,并结合使用通过 Operators.bool_op()
方法的自定义运算符来实现。对于具有一定程度跨后端兼容性的简单情况,也可以使用 Operators.match()
运算符。
使用 match()
的简单纯文本匹配¶
Operators.match()
运算符提供跨兼容的简单文本匹配。对于 PostgreSQL 后端,它被硬编码为生成使用 @@
运算符与 plainto_tsquery()
PostgreSQL 函数结合使用的表达式。
在 PostgreSQL 方言中,如下所示的表达式
select(sometable.c.text.match("search string"))
将向数据库发出
SELECT text @@ plainto_tsquery('search string') FROM table
在上面,将纯字符串传递给 Operators.match()
将自动使用 plainto_tsquery()
来指定 tsquery 的类型。这为 Operators.match()
与其他后端建立了基本的数据库跨兼容性。
在版本 2.0 中更改: PostgreSQL 方言与 Operators.match()
一起使用的默认 tsquery 生成函数是 plainto_tsquery()
。
要渲染与 1.4 版本中完全相同的内容,请使用以下形式
from sqlalchemy import func
select(sometable.c.text.bool_op("@@")(func.to_tsquery("search string")))
这将发出
SELECT text @@ to_tsquery('search string') FROM table
直接使用 PostgreSQL 全文函数和运算符¶
超出简单使用 Operators.match()
的文本搜索操作可以使用 func
命名空间来生成 PostgreSQL 全文函数,并结合 Operators.bool_op()
来生成任何布尔运算符。
例如,查询
select(func.to_tsquery("cat").bool_op("@>")(func.to_tsquery("cat & rat")))
将生成
SELECT to_tsquery('cat') @> to_tsquery('cat & rat')
TSVECTOR
类型可以提供显式 CAST
from sqlalchemy.dialects.postgresql import TSVECTOR
from sqlalchemy import select, cast
select(cast("some text", TSVECTOR))
生成等效于以下语句的语句
SELECT CAST('some text' AS TSVECTOR) AS anon_1
func
命名空间由 PostgreSQL 方言增强,以为大多数全文搜索函数设置正确的参数和返回类型。假设已导入 sqlalchemy.dialects.postgresql
包,或者已使用 postgresql
方言调用 create_engine()
,则 sqlalchemy.sql.expression.func
命名空间会自动使用这些函数。这些函数的文档位于
使用 match()
或自定义运算符指定 “regconfig”¶
PostgreSQL 的 plainto_tsquery()
函数接受一个可选的 “regconfig” 参数,该参数用于指示 PostgreSQL 使用特定的预计算 GIN 或 GiST 索引来执行搜索。当使用 Operators.match()
时,可以使用 postgresql_regconfig
参数指定此附加参数,例如
select(mytable.c.id).where(
mytable.c.title.match("somestring", postgresql_regconfig="english")
)
这将发出
SELECT mytable.id FROM mytable
WHERE mytable.title @@ plainto_tsquery('english', 'somestring')
当将其他 PostgreSQL 搜索函数与 func
一起使用时,“regconfig” 参数可以直接作为初始参数传递
select(mytable.c.id).where(
func.to_tsvector("english", mytable.c.title).bool_op("@@")(
func.to_tsquery("english", "somestring")
)
)
生成等效于以下语句的语句
SELECT mytable.id FROM mytable
WHERE to_tsvector('english', mytable.title) @@
to_tsquery('english', 'somestring')
建议您使用 PostgreSQL 中的 EXPLAIN ANALYZE...
工具,以确保您使用 SQLAlchemy 生成的查询充分利用了您可能为全文搜索创建的任何索引。
另请参阅
全文搜索 - 在 PostgreSQL 文档中
FROM ONLY …¶
该方言支持 PostgreSQL 的 ONLY 关键字,用于仅定位继承层次结构中的特定表。这可以用于生成 SELECT ... FROM ONLY
、UPDATE ONLY ...
和 DELETE FROM ONLY ...
语法。它使用 SQLAlchemy 的 hints 机制
# 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 版本新增。
部分索引¶
部分索引向索引定义添加条件,以便将索引应用于行的子集。这些可以使用 postgresql_where
关键字参数在 Index
上指定
Index("my_index", my_table.c.id, postgresql_where=my_table.c.value > 10)
运算符类¶
PostgreSQL 允许为索引的每一列指定一个运算符类(请参阅 https://postgresql.ac.cn/docs/current/interactive/indexes-opclass.html)。Index
构造允许通过 postgresql_ops
关键字参数指定这些运算符类
Index(
"my_index",
my_table.c.id,
my_table.c.data,
postgresql_ops={"data": "text_pattern_ops", "id": "int4_ops"},
)
请注意,postgresql_ops
字典中的键是 Column
的 “key” 名称,即用于从 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
的运算符类的支持。
索引类型¶
PostgreSQL 提供了几种索引类型:B-Tree、Hash、GiST 和 GIN,以及用户创建自己的索引类型的功能(请参阅 https://postgresql.ac.cn/docs/current/static/indexes-types.html)。这些可以使用 postgresql_using
关键字参数在 Index
上指定
Index("my_index", my_table.c.data, postgresql_using="gin")
传递给关键字参数的值将简单地传递到基础 CREATE INDEX 命令,因此它必须是您的 PostgreSQL 版本有效的索引类型。
索引存储参数¶
PostgreSQL 允许在索引上设置存储参数。可用的存储参数取决于索引使用的索引方法。可以使用 postgresql_with
关键字参数在 Index
上指定存储参数
Index("my_index", my_table.c.data, postgresql_with={"fillfactor": 50})
PostgreSQL 允许定义在其中创建索引的表空间。可以使用 postgresql_tablespace
关键字参数在 Index
上指定表空间
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 或更高版本,或者对于无连接方言,则渲染为
CREATE INDEX CONCURRENTLY test_idx1 ON testtbl (data)
对于 DROP INDEX,假设检测到 PostgreSQL 9.2 或更高版本,或者对于无连接方言,它将发出
DROP INDEX CONCURRENTLY test_idx1
当使用 CONCURRENTLY 时,PostgreSQL 数据库要求语句在事务块之外调用。Python DBAPI 强制即使对于单个语句,也存在事务,因此要使用此构造,必须使用 DBAPI 的 “autocommit” 模式
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 索引反射¶
每当使用 UNIQUE CONSTRAINT 构造时,PostgreSQL 数据库都会隐式创建 UNIQUE INDEX。当使用 Inspector
检查表时,Inspector.get_indexes()
和 Inspector.get_unique_constraints()
将分别报告这两种构造;对于索引,如果检测到索引正在镜像约束,则索引条目中将存在键 duplicates_constraint
。当使用 Table(..., autoload_with=engine)
执行反射时,当检测到 UNIQUE INDEX 正在镜像 UniqueConstraint
在 Table.constraints
集合中时,不会在 Table.indexes
中返回 UNIQUE INDEX。
特殊反射选项¶
用于 PostgreSQL 后端的 Inspector
是 PGInspector
的实例,它提供了其他方法
from sqlalchemy import create_engine, inspect
engine = create_engine("postgresql+psycopg2://127.0.0.1/test")
insp = inspect(engine) # will be a PGInspector
print(insp.get_enums())
对象名称 | 描述 |
---|---|
- class sqlalchemy.dialects.postgresql.base.PGInspector¶
-
-
method
sqlalchemy.dialects.postgresql.base.PGInspector.
get_domains(schema: str | None = None) → List[ReflectedDomain]¶ 返回 DOMAIN 对象的列表。
每个成员都是一个包含以下字段的字典
name - 域的名称
schema - 域的模式名称。
visible - 布尔值,指示此域在默认搜索路径中是否可见。
type - 由此域定义的类型。
nullable - 指示此域是否可以为
NULL
。default - 域的默认值,如果域没有默认值,则为
None
。constraints - 约束 - 由该域定义的约束字典列表。每个元素约束两个键:约束的
name
(名称)和包含约束文本的check
(检查)。
- 参数:
schema¶ – 模式名称。如果为 None,则使用默认模式(通常为 ‘public’)。也可以设置为
'*'
以指示加载所有模式的域。
2.0 版本新增。
-
method
sqlalchemy.dialects.postgresql.base.PGInspector.
get_enums(schema: str | None = None) → List[ReflectedEnum]¶ 返回 ENUM 对象的列表。
每个成员都是一个包含以下字段的字典
name - 枚举的名称
schema - 枚举的模式名称。
visible - 布尔值,指示此枚举在默认搜索路径中是否可见。
labels - 应用于枚举的字符串标签列表。
- 参数:
schema¶ – 模式名称。如果为 None,则使用默认模式(通常为 ‘public’)。也可以设置为
'*'
以指示加载所有模式的枚举。
-
method
sqlalchemy.dialects.postgresql.base.PGInspector.
get_foreign_table_names(schema: str | None = None) → List[str]¶ 返回 FOREIGN TABLE (外部表)名称的列表。
行为类似于
Inspector.get_table_names()
的行为,但该列表仅限于报告relkind
值为f
的表。
-
method
sqlalchemy.dialects.postgresql.base.PGInspector.
get_table_oid(table_name: str, schema: str | None = None) → int¶ 返回给定表名称的 OID。
- 参数:
table_name¶ – 表的字符串名称。对于特殊引用,请使用
quoted_name
。schema¶ – 字符串模式名称;如果省略,则使用数据库连接的默认模式。对于特殊引用,请使用
quoted_name
。
-
method
sqlalchemy.dialects.postgresql.base.PGInspector.
has_type(type_name: str, schema: str | None = None, **kw: Any) → bool¶ 如果数据库在提供的模式中具有指定的类型,则返回 True。
2.0 版本新增。
-
method
PostgreSQL 表选项¶
PostgreSQL 方言直接支持几个 CREATE TABLE 选项,与 Table
构造结合使用
INHERITS (继承)
:Table("some_table", metadata, ..., postgresql_inherits="some_supertable") Table("some_table", metadata, ..., postgresql_inherits=("t1", "t2", ...))
ON COMMIT (在提交时)
:Table("some_table", metadata, ..., postgresql_on_commit="PRESERVE ROWS")
PARTITION BY (分区依据)
:Table( "some_table", metadata, ..., postgresql_partition_by="LIST (part_column)", )
1.2.6 版本新增。
TABLESPACE (表空间)
:Table("some_table", metadata, ..., postgresql_tablespace="some_tablespace")
以上选项也适用于
Index
构造。USING (使用)
:Table("some_table", metadata, ..., postgresql_using="heap")
2.0.26 版本新增。
WITH OIDS (使用 OID)
:Table("some_table", metadata, ..., postgresql_with_oids=True)
WITHOUT OIDS (不使用 OID)
:Table("some_table", metadata, ..., postgresql_with_oids=False)
另请参阅
PostgreSQL CREATE TABLE options - 在 PostgreSQL 文档中。
PostgreSQL 约束选项¶
以下选项受 PostgreSQL 方言支持,并与选定的约束构造结合使用
NOT VALID
(无效):此选项适用于 CHECK (检查)和 FOREIGN KEY (外键)约束,当通过 ALTER TABLE 将约束添加到现有表时,并且具有在 ALTER 操作期间不扫描现有行以针对正在添加的约束的效果。当使用 SQL 迁移工具(例如 Alembic)渲染 ALTER TABLE 构造时,可以在创建约束的操作中将
postgresql_not_valid
参数指定为额外的关键字参数,如下面的 Alembic 示例所示def update(): op.create_foreign_key( "fk_user_address", "address", "user", ["user_id"], ["id"], postgresql_not_valid=True, )
该关键字最终由
CheckConstraint
、ForeignKeyConstraint
和ForeignKey
构造直接接受;当使用像 Alembic 这样的工具时,方言特定的关键字参数将从迁移操作指令传递到这些构造。CheckConstraint("some_field IS NOT NULL", postgresql_not_valid=True) ForeignKeyConstraint( ["some_id"], ["some_table.some_id"], postgresql_not_valid=True )
1.4.32 版本新增。
另请参阅
PostgreSQL ALTER TABLE options - 在 PostgreSQL 文档中。
表值、表值函数和列值函数、行和元组对象¶
PostgreSQL 大量使用了现代 SQL 形式,例如表值函数、表和行作为值。这些构造通常用作 PostgreSQL 对复杂数据类型(如 JSON、ARRAY 和其他数据类型)支持的一部分。SQLAlchemy 的 SQL 表达式语言对大多数表值和行值形式具有原生支持。
表值函数¶
许多 PostgreSQL 内置函数旨在用于 SELECT 语句的 FROM 子句中,并且能够返回表行或表行集。例如,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
对象。
以下是 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_1json_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 xjson_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
向函数的输出添加序号计数器,并被包括unnest()
和generate_series()
在内的有限的 PostgreSQL 函数集接受。FunctionElement.table_valued()
方法为此目的接受关键字参数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 版本新增。
另请参阅
表值函数 - 在 SQLAlchemy 统一教程 中
列值函数¶
与表值函数类似,列值函数也存在于 FROM 子句中,但作为单个标量值传递到列子句中。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 xunnest()
- 为了生成 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
另请参阅
行类型¶
可以使用 func.ROW
和 sqlalchemy.func
命名空间,或使用 tuple_()
构造来近似内置的 ROW
渲染支持。
>>> 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)
传递给函数的表类型¶
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 版本新增。
ARRAY 类型¶
PostgreSQL 方言支持数组,既支持作为多维列类型,也支持作为数组文字。
ARRAY
- ARRAY 数据类型array
- 数组文字array_agg()
- ARRAY_AGG SQL 函数aggregate_order_by
- PG 的 ORDER BY 聚合函数语法的助手。
JSON 类型¶
PostgreSQL 方言支持 JSON 和 JSONB 数据类型,包括 psycopg2 的原生支持以及对 PostgreSQL 所有特殊运算符的支持。
HSTORE 类型¶
支持 PostgreSQL HSTORE 类型以及 hstore 文字。
ENUM 类型¶
PostgreSQL 具有独立创建的 TYPE 结构,用于实现枚举类型。这种方法在 SQLAlchemy 方面引入了显著的复杂性,涉及何时应该 CREATE 和 DROP 此类型。类型对象也是一个独立的可反射实体。应参考以下各节:
ENUM
- ENUM 的 DDL 和类型支持。PGInspector.get_enums()
- 检索当前 ENUM 类型的列表ENUM.create()
,ENUM.drop()
- ENUM 的单独 CREATE 和 DROP 命令。
将 ENUM 与 ARRAY 结合使用¶
目前,后端 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 方言仅支持 range 类型。
2.0.17 版本新增:为 pg8000 方言添加了 range 和 multirange 支持。需要 pg8000 1.29.8 或更高版本。
传递到数据库的数据值可以作为字符串值传递,也可以使用 Range
数据对象传递。
2.0 版本新增:添加了后端无关的 Range
对象,用于指示范围。psycopg2
特定的 range 类不再公开,仅在特定方言内部使用。
例如,一个完全类型化的模型示例,使用 TSRANGE
数据类型
from datetime import datetime
from sqlalchemy.dialects.postgresql import Range
from sqlalchemy.dialects.postgresql import TSRANGE
from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
class Base(DeclarativeBase):
pass
class RoomBooking(Base):
__tablename__ = "room_booking"
id: Mapped[int] = mapped_column(primary_key=True)
room: Mapped[str]
during: Mapped[Range[datetime]] = mapped_column(TSRANGE)
为了表示上面 during
列的数据,Range
类型是一个简单的 dataclass,它将表示范围的边界。下面说明了将行插入到上面的 room_booking
表中
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
engine = create_engine("postgresql+psycopg://scott:tiger@pg14/dbname")
Base.metadata.create_all(engine)
with Session(engine) as session:
booking = RoomBooking(
room="101", during=Range(datetime(2013, 3, 23), datetime(2013, 3, 25))
)
session.add(booking)
session.commit()
从任何 range 列中选择也将返回 Range
对象,如所示
from sqlalchemy import select
with Session(engine) as session:
for row in session.execute(select(RoomBooking.during)):
print(row)
可用的 range 数据类型如下:
对象名称 | 描述 |
---|---|
表示 PostgreSQL 范围。 |
- class sqlalchemy.dialects.postgresql.Range¶
表示 PostgreSQL 范围。
例如:
r = Range(10, 50, bounds="()")
调用样式类似于 psycopg 和 psycopg2 的样式,部分原因是允许更容易地从以前直接使用这些对象的 SQLAlchemy 版本进行迁移。
- 参数:
2.0 版本新增。
成员
__eq__(), adjacent_to(), contained_by(), contains(), difference(), intersection(), is_empty, isempty, lower, lower_inc, lower_inf, not_extend_left_of(), not_extend_right_of(), overlaps(), strictly_left_of(), strictly_right_of(), union(), upper, upper_inc, upper_inf
类签名
class
sqlalchemy.dialects.postgresql.Range
(typing.Generic
)-
method
sqlalchemy.dialects.postgresql.Range.
__eq__(other: Any) → bool¶ 将此范围与 other 进行比较,同时考虑边界的包含性,如果它们相等,则返回
True
。
-
method
sqlalchemy.dialects.postgresql.Range.
adjacent_to(other: Range[_T]) → bool¶ 确定此范围是否与 other 相邻。
-
method
sqlalchemy.dialects.postgresql.Range.
contained_by(other: Range[_T]) → bool¶ 确定此范围是否被 other 包含。
-
method
sqlalchemy.dialects.postgresql.Range.
contains(value: _T | Range[_T]) → bool¶ 确定此范围是否包含 value。
-
method
sqlalchemy.dialects.postgresql.Range.
difference(other: Range[_T]) → Range[_T]¶ 计算此范围与 other 之间的差集。
如果两个范围“不相交”,即既不相邻也不重叠,则会引发
ValueError
异常。
-
method
sqlalchemy.dialects.postgresql.Range.
intersection(other: Range[_T]) → Range[_T]¶ 计算此范围与 other 的交集。
2.0.10 版本新增。
-
attribute
sqlalchemy.dialects.postgresql.Range.
is_empty¶ ‘empty’ 属性的同义词。
-
attribute
sqlalchemy.dialects.postgresql.Range.
isempty¶ ‘empty’ 属性的同义词。
-
attribute
sqlalchemy.dialects.postgresql.Range.
lower: _T | None¶ 下界
-
attribute
sqlalchemy.dialects.postgresql.Range.
lower_inc¶ 如果下界是包含的,则返回 True。
-
attribute
sqlalchemy.dialects.postgresql.Range.
lower_inf¶ 如果此范围非空且下界为无穷大,则返回 True。
-
method
sqlalchemy.dialects.postgresql.Range.
not_extend_left_of(other: Range[_T]) → bool¶ 确定此范围是否不向 other 的左侧延伸。
-
method
sqlalchemy.dialects.postgresql.Range.
not_extend_right_of(other: Range[_T]) → bool¶ 确定此范围是否不向 other 的右侧延伸。
-
method
sqlalchemy.dialects.postgresql.Range.
overlaps(other: Range[_T]) → bool¶ 确定此范围是否与 other 重叠。
-
method
sqlalchemy.dialects.postgresql.Range.
strictly_left_of(other: Range[_T]) → bool¶ 确定此范围是否完全在 other 的左侧。
-
method
sqlalchemy.dialects.postgresql.Range.
strictly_right_of(other: Range[_T]) → bool¶ 确定此范围是否完全在 other 的右侧。
-
method
sqlalchemy.dialects.postgresql.Range.
union(other: Range[_T]) → Range[_T]¶ 计算此范围与 other 的并集。
如果两个范围“不相交”,即既不相邻也不重叠,则会引发
ValueError
异常。
-
attribute
sqlalchemy.dialects.postgresql.Range.
upper: _T | None¶ 上界
-
attribute
sqlalchemy.dialects.postgresql.Range.
upper_inc¶ 如果上界是包含的,则返回 True。
-
attribute
sqlalchemy.dialects.postgresql.Range.
upper_inf¶ 如果此范围非空且上界为无穷大,则返回 True。
多范围¶
PostgreSQL 14 及以上版本支持多范围。SQLAlchemy 的多范围数据类型处理 Range
类型列表。
仅 在 psycopg、asyncpg 和 pg8000 方言上支持多范围。psycopg2 方言是 SQLAlchemy 的默认 postgresql
方言,不 支持多范围数据类型。
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
类型列表不会自动检测到特定列表值的就地更改;要使用 ORM 更新列表值,请将新列表重新分配给属性,或使用 MutableList
类型修饰符。有关背景信息,请参阅 Mutation Tracking 部分。
使用 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}")
使用简单的 list
而不是 MultiRange
将需要手动将字面量值的类型设置为适当的多范围类型。
2.0.26 版本新增: 添加了 MultiRange
序列。
可用的多范围数据类型如下
网络数据类型¶
对于 INET
和 CIDR
数据类型,有条件地支持发送和检索 Python ipaddress
对象,包括 ipaddress.IPv4Network
、ipaddress.IPv6Network
、ipaddress.IPv4Address
、ipaddress.IPv6Address
。此支持目前是 DBAPI 本身 的默认行为,并且因 DBAPI 而异。SQLAlchemy 尚未实现其自身的网络地址转换逻辑。
psycopg2 方言仅发送和接收字符串。
pg8000 方言支持
INET
数据类型的ipaddress.IPv4Address
和ipaddress.IPv6Address
对象,但CIDR
类型使用字符串。
要将以上所有 DBAPI 规范化为仅返回字符串,请使用 native_inet_types
参数,并传递 False
值
e = create_engine(
"postgresql+psycopg://scott:tiger@host/dbname", native_inet_types=False
)
使用上述参数,psycopg
、asyncpg
和 pg8000
方言将禁用 DBAPI 对这些类型的适配,并且将仅返回字符串,从而与旧的 psycopg2
方言的行为相匹配。
该参数也可以设置为 True
,在这种情况下,对于那些不支持或尚未完全支持将行转换为 Python ipaddress
数据类型的后端(目前为 psycopg2 和 pg8000),它将引发 NotImplementedError
。
2.0.18 版本新增: - 添加了 native_inet_types
参数。
PostgreSQL 数据类型¶
与所有 SQLAlchemy 方言一样,所有已知对 PostgreSQL 有效的大写类型都可以从顶级方言导入,无论它们是源自 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 特定构造参数的类型如下:
对象名称 | 描述 |
---|---|
PostgreSQL MULTIRANGE 类型的基类。 |
|
单个和多范围 SQL 类型的基类。 |
|
PostgreSQL RANGE 类型的基类。 |
|
PostgreSQL ARRAY 类型。 |
|
提供 PostgreSQL CITEXT 类型。 |
|
表示 PostgreSQL DATEMULTIRANGE 类型。 |
|
表示 PostgreSQL DATERANGE 类型。 |
|
表示 DOMAIN PostgreSQL 类型。 |
|
PostgreSQL ENUM 类型。 |
|
表示 PostgreSQL HSTORE 类型。 |
|
表示 PostgreSQL INT4MULTIRANGE 类型。 |
|
表示 PostgreSQL INT4RANGE 类型。 |
|
表示 PostgreSQL INT8MULTIRANGE 类型。 |
|
表示 PostgreSQL INT8RANGE 类型。 |
|
PostgreSQL INTERVAL 类型。 |
|
表示 PostgreSQL JSON 类型。 |
|
表示 PostgreSQL JSONB 类型。 |
|
JSON Path 类型。 |
|
提供 PostgreSQL MONEY 类型。 |
|
表示多范围序列。 |
|
表示 PostgreSQL NUMMULTIRANGE 类型。 |
|
表示 PostgreSQL NUMRANGE 类型。 |
|
提供 PostgreSQL OID 类型。 |
|
提供 PostgreSQL REGCLASS 类型。 |
|
提供 PostgreSQL REGCONFIG 类型。 |
|
PostgreSQL TIME 类型。 |
|
提供 PostgreSQL TIMESTAMP 类型。 |
|
表示 PostgreSQL TSRANGE 类型。 |
|
提供 PostgreSQL TSQUERY 类型。 |
|
表示 PostgreSQL TSRANGE 类型。 |
|
表示 PostgreSQL TSTZRANGE 类型。 |
|
表示 PostgreSQL TSTZRANGE 类型。 |
|
|
- class sqlalchemy.dialects.postgresql.AbstractRange¶
单个和多范围 SQL 类型的基类。
成员
adjacent_to(), contained_by(), contains(), difference(), intersection(), not_extend_left_of(), not_extend_right_of(), overlaps(), strictly_left_of(), strictly_right_of(), union()
- class comparator_factory¶
定义范围类型的比较操作。
类签名
class
sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory
(sqlalchemy.types.Comparator
)-
method
sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.
adjacent_to(other: Any) → ColumnElement[bool]¶ 布尔表达式。如果列中的范围与操作数中的范围相邻,则返回 true。
-
method
sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.
contained_by(other: Any) → ColumnElement[bool]¶ 布尔表达式。如果列包含在右手操作数中,则返回 true。
-
method
sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.
contains(other: Any, **kw: Any) → ColumnElement[bool]¶ 布尔表达式。如果右手操作数(可以是元素或范围)包含在列中,则返回 true。
kwargs 可能会被此运算符忽略,但 API 一致性需要它。
-
method
sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.
difference(other: Any) → ColumnElement[bool]¶ 范围表达式。返回两个范围的并集。如果结果范围不连续,将引发异常。
-
method
sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.
intersection(other: Any) → ColumnElement[Range[_T]]¶ 范围表达式。返回两个范围的交集。如果结果范围不连续,将引发异常。
-
method
sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.
not_extend_left_of(other: Any) → ColumnElement[bool]¶ 布尔表达式。如果列中的范围不向操作数中的范围左侧延伸,则返回 true。
-
method
sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.
not_extend_right_of(other: Any) → ColumnElement[bool]¶ 布尔表达式。如果列中的范围不向操作数中的范围右侧延伸,则返回 true。
-
method
sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.
overlaps(other: Any) → ColumnElement[bool]¶ 布尔表达式。如果列与右手操作数重叠(具有共同点),则返回 true。
-
method
sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.
strictly_left_of(other: Any) → ColumnElement[bool]¶ 布尔表达式。如果列严格位于右手操作数的左侧,则返回 true。
-
method
sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.
strictly_right_of(other: Any) → ColumnElement[bool]¶ 布尔表达式。如果列严格位于右手操作数的右侧,则返回 true。
-
method
sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.
union(other: Any) → ColumnElement[bool]¶ 范围表达式。返回两个范围的并集。如果结果范围不连续,将引发异常。
-
method
- class sqlalchemy.dialects.postgresql.AbstractSingleRange¶
PostgreSQL RANGE 类型的基类。
这些是返回单个
Range
对象的类型。另请参阅
- class sqlalchemy.dialects.postgresql.AbstractMultiRange¶
PostgreSQL MULTIRANGE 类型的基类。
这些是返回
Range
对象序列的类型。
- class sqlalchemy.dialects.postgresql.ARRAY¶
PostgreSQL ARRAY 类型。
ARRAY
类型以与核心ARRAY
类型相同的方式构建; 成员类型是必需的,如果该类型将用于多个维度,则建议使用维度数量from sqlalchemy.dialects import postgresql mytable = Table( "mytable", metadata, Column("data", postgresql.ARRAY(Integer, dimensions=2)), )
ARRAY
类型提供了核心ARRAY
类型上定义的所有操作,包括对“维度”、索引访问和简单匹配(例如Comparator.any()
和Comparator.all()
)的支持。ARRAY
类还提供了 PostgreSQL 特有的包含操作方法,包括Comparator.contains()
、Comparator.contained_by()
和Comparator.overlap()
,例如:mytable.c.data.contains([1, 2])
默认情况下,索引访问是基于 1 的,以匹配 PostgreSQL; 对于基于 0 的索引访问,请设置
ARRAY.zero_indexes
。此外,
ARRAY
类型不能直接与ENUM
类型结合使用。 有关解决方法,请参阅 将 ENUM 与 ARRAY 结合使用 中的特殊类型。在使用 ORM 时检测 ARRAY 列中的更改
当与 SQLAlchemy ORM 一起使用时,
ARRAY
类型不会检测到对数组的就地修改。 为了检测这些修改,必须使用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 元素将始终触发更改事件。
-
method
sqlalchemy.dialects.postgresql.ARRAY.
__init__(item_type: _TypeEngineArgument[Any], as_tuple: bool = False, dimensions: int | None = None, zero_indexes: bool = False)¶ 构造 ARRAY。
例如:
Column("myarray", ARRAY(Integer))
参数包括:
- 参数:
item_type¶ – 此数组项的数据类型。 请注意,维度在这里是不相关的,因此像
INTEGER[][]
这样的多维数组被构造为ARRAY(Integer)
,而不是ARRAY(ARRAY(Integer))
等。as_tuple=False¶ – 指定返回结果是否应从列表转换为元组。 诸如 psycopg2 之类的 DBAPI 默认返回列表。 当返回元组时,结果是可哈希的。
dimensions¶ – 如果为非 None,则 ARRAY 将假定固定的维度数。 这将导致为此 ARRAY 发出的 DDL 包括确切的括号子句
[]
的数量,并且还将优化类型的整体性能。 请注意,PG 数组始终是隐式“非维度”的,这意味着无论它们是如何声明的,它们都可以存储任意数量的维度。zero_indexes=False¶ – 当为 True 时,索引值将在 Python 基于 0 的索引和 PostgreSQL 基于 1 的索引之间进行转换,例如,在传递到数据库之前,索引值都将加 1。
- class Comparator¶
为
ARRAY
定义比较运算。请注意,这些操作是对基础
Comparator
类提供的操作的补充,包括Comparator.any()
和Comparator.all()
。类签名
class
sqlalchemy.dialects.postgresql.ARRAY.Comparator
(sqlalchemy.types.Comparator
)-
method
sqlalchemy.dialects.postgresql.ARRAY.Comparator.
contains(other, **kwargs)¶ 布尔表达式。 测试元素是否是参数数组表达式元素的超集。
kwargs 可能会被此运算符忽略,但 API 一致性需要它。
-
method
sqlalchemy.dialects.postgresql.ARRAY.Comparator.
contained_by(other)¶ 布尔表达式。 测试元素是否是参数数组表达式元素的真子集。
-
method
sqlalchemy.dialects.postgresql.ARRAY.Comparator.
overlap(other)¶ 布尔表达式。 测试数组是否与参数数组表达式有共同的元素。
-
method
-
method
- class sqlalchemy.dialects.postgresql.BIT¶
- class sqlalchemy.dialects.postgresql.BYTEA¶
成员
-
method
sqlalchemy.dialects.postgresql.BYTEA.
__init__(length: int | None = None)¶ 继承自
sqlalchemy.types.LargeBinary.__init__
方法,该方法属于LargeBinary
构造 LargeBinary 类型。
- 参数:
length¶ – 可选,用于 DDL 语句的列长度,适用于接受长度的二进制类型,例如 MySQL BLOB 类型。
-
method
- class sqlalchemy.dialects.postgresql.CIDR¶
类签名
class
sqlalchemy.dialects.postgresql.CIDR
(sqlalchemy.dialects.postgresql.types._NetworkAddressTypeMixin
,sqlalchemy.types.TypeEngine
)
- class sqlalchemy.dialects.postgresql.CITEXT¶
提供 PostgreSQL CITEXT 类型。
2.0.7 版本新增。
成员
-
method
sqlalchemy.dialects.postgresql.CITEXT.
__init__(length: int | None = None, collation: str | None = None)¶ 继承自
sqlalchemy.types.String.__init__
方法,该方法属于String
创建字符串类型的持有器。
- 参数:
length¶ – 可选,用于 DDL 和 CAST 表达式的列长度。 如果不发出
CREATE TABLE
,则可以安全地省略。 某些数据库可能需要length
以用于 DDL,并且如果包含没有长度的VARCHAR
,则在发出CREATE TABLE
DDL 时会引发异常。 该值被解释为字节还是字符取决于具体的数据库。collation¶ –
可选,列级别的排序规则,用于 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注意
在大多数情况下,
Unicode
或UnicodeText
数据类型应用于期望存储非 ASCII 数据的Column
。 这些数据类型将确保在数据库上使用正确的类型。
-
method
- class sqlalchemy.dialects.postgresql.DOMAIN¶
表示 DOMAIN PostgreSQL 类型。
域本质上是一种数据类型,带有可选的约束,用于限制允许的值集。 例如:
PositiveInt = DOMAIN("pos_int", Integer, check="VALUE > 0", not_null=True) UsPostalCode = DOMAIN( "us_postal_code", Text, check="VALUE ~ '^\d{5}$' OR VALUE ~ '^\d{5}-\d{4}$'", )
有关更多详细信息,请参阅 PostgreSQL 文档
2.0 版本新增。
成员
类签名
class
sqlalchemy.dialects.postgresql.DOMAIN
(sqlalchemy.dialects.postgresql.named_types.NamedType
,sqlalchemy.types.SchemaType
)-
method
sqlalchemy.dialects.postgresql.DOMAIN.
__init__(name: str, data_type: _TypeEngineArgument[Any], *, collation: str | None = None, default: elements.TextClause | str | None = None, constraint_name: str | None = None, not_null: bool | None = None, check: elements.TextClause | str | None = None, create_type: bool = True, **kw: Any)¶ 构造 DOMAIN。
- 参数:
name¶ – 域的名称
data_type¶ – 域的底层数据类型。 这可以包括数组说明符。
collation¶ – 域的可选排序规则。 如果未指定排序规则,则使用底层数据类型的默认排序规则。 如果指定了
collation
,则底层类型必须是可排序的。default¶ – DEFAULT 子句指定域数据类型列的默认值。 默认值应为字符串或
text()
值。 如果未指定默认值,则默认值为 null 值。constraint_name¶ – 约束的可选名称。 如果未指定,则后端会生成一个名称。
not_null¶ – 阻止此域的值为空。 默认情况下,域允许为空。 如果未指定,则不会发出非空子句。
check¶ – CHECK 子句指定完整性约束或测试,域的值必须满足该约束或测试。 约束必须是生成布尔结果的表达式,该表达式可以使用关键字 VALUE 来引用被测试的值。 与 PostgreSQL 不同,SQLAlchemy 中目前只允许使用单个 check 子句。
schema¶ – 可选的模式名称
create_type¶ – 默认为 True。 指示在创建父表时,应发出
CREATE TYPE
,并在可选地检查类型的存在之后; 此外,当删除表时,将调用DROP TYPE
。
-
method
sqlalchemy.dialects.postgresql.DOMAIN.
create(bind, checkfirst=True, **kw)¶ 继承自
NamedType.create()
方法,该方法属于NamedType
为此类型发出
CREATE
DDL。- 参数:
bind¶ – 可连接的
Engine
、Connection
或类似对象,用于发出 SQL。checkfirst¶ – 如果为
True
,则首先针对 PG 目录执行查询,以查看在创建之前类型是否已存在。
-
method
sqlalchemy.dialects.postgresql.DOMAIN.
drop(bind, checkfirst=True, **kw)¶ 继承自
NamedType.drop()
方法,该方法属于NamedType
为此类型发出
DROP
DDL。- 参数:
bind¶ – 可连接的
Engine
、Connection
或类似对象,用于发出 SQL。checkfirst¶ – 如果为
True
,则首先针对 PG 目录执行查询,以查看在删除之前类型是否实际存在。
-
method
- class sqlalchemy.dialects.postgresql.DOUBLE_PRECISION
SQL DOUBLE PRECISION 类型。
2.0 版本新增。
另请参阅
Double
- 基础类型的文档。类签名
class
sqlalchemy.dialects.postgresql.DOUBLE_PRECISION
(sqlalchemy.types.Double
)-
方法
sqlalchemy.dialects.postgresql.DOUBLE_PRECISION.
__init__(precision: int | None = None, asdecimal: bool = False, decimal_return_scale: int | None = None) 继承自
sqlalchemy.types.Float.__init__
方法,源于Float
构造一个 Float 类型。
- 参数:
precision¶ –
用于 DDL
CREATE TABLE
的数值精度。后端应该尝试确保此精度指示通用Float
数据类型的位数。注意
对于 Oracle 数据库后端,渲染 DDL 时不接受
Float.precision
参数,因为 Oracle 数据库不支持以十进制位数指定的浮点精度。请改用 Oracle 数据库特定的FLOAT
数据类型,并指定FLOAT.binary_precision
参数。这是 SQLAlchemy 2.0 版本中的新功能。要创建一个数据库无关的
Float
,该类型为 Oracle 数据库单独指定二进制精度,请使用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 十进制数时使用的默认刻度。 由于十进制不精确,浮点值通常会更长,并且大多数浮点数据库类型都没有“刻度”的概念,因此默认情况下,浮点类型在转换时会查找前十位小数位。 指定此值将覆盖该长度。 请注意,MySQL 浮点类型(确实包含“刻度”)如果未另行指定,将使用“刻度”作为 decimal_return_scale 的默认值。
-
方法
- class sqlalchemy.dialects.postgresql.ENUM¶
PostgreSQL ENUM 类型。
这是
Enum
的子类,它包含对 PG 的CREATE TYPE
和DROP TYPE
的支持。当使用内置类型
Enum
且Enum.native_enum
标志保留其默认值 True 时,PostgreSQL 后端将使用ENUM
类型作为实现,因此将使用特殊的创建/删除规则。ENUM 的创建/删除行为必然是复杂的,因为 ENUM 类型与父表的关系很尴尬,因为它可能只由单个表“拥有”,也可能在多个表之间共享。
当以“内联”方式使用
Enum
或ENUM
时,CREATE TYPE
和DROP TYPE
会在调用Table.create()
和Table.drop()
方法时发出table = Table( "sometable", metadata, Column("some_enum", ENUM("a", "b", "c", name="myenum")), ) table.create(engine) # will emit CREATE ENUM and CREATE TABLE table.drop(engine) # will emit DROP TABLE and DROP ENUM
要在多个表之间使用通用的枚举类型,最佳实践是独立声明
Enum
或ENUM
,并将其与MetaData
对象本身关联my_enum = ENUM("a", "b", "c", name="myenum", metadata=metadata) t1 = Table("sometable_one", metadata, Column("some_enum", myenum)) t2 = Table("sometable_two", metadata, Column("some_enum", myenum))
当使用此模式时,仍然必须在单个表创建级别注意。 发出 CREATE TABLE 而不指定
checkfirst=True
仍然会导致问题t1.create(engine) # will fail: no such type 'myenum'
如果我们指定
checkfirst=True
,则单个表级别的创建操作将检查ENUM
,如果不存在则创建# will check if enum exists, and emit CREATE TYPE if not t1.create(engine, checkfirst=True)
当使用元数据级别的 ENUM 类型时,如果调用了元数据范围的创建/删除,则始终会创建和删除该类型
metadata.create_all(engine) # will emit CREATE TYPE metadata.drop_all(engine) # will emit DROP TYPE
该类型也可以直接创建和删除
my_enum.create(engine) my_enum.drop(engine)
成员
类签名
class
sqlalchemy.dialects.postgresql.ENUM
(sqlalchemy.dialects.postgresql.named_types.NamedType
,sqlalchemy.types.NativeForEmulated
,sqlalchemy.types.Enum
)-
方法
sqlalchemy.dialects.postgresql.ENUM.
__init__(*enums, name: str | _NoArg | None = _NoArg.NO_ARG, create_type: bool = True, **kw)¶ 构造一个
ENUM
。参数与
Enum
的参数相同,但还包括以下参数。- 参数:
create_type¶ – 默认为 True。 表示当创建父表时,应发出
CREATE TYPE
,并可选择在发出之前检查类型是否存在; 此外,当删除表时,会调用DROP TYPE
。 当为False
时,将不执行检查,也不会发出CREATE TYPE
或DROP TYPE
,除非直接调用ENUM.create()
或ENUM.drop()
。 当在无法访问实际数据库的情况下调用 SQL 文件的创建方案时,将设置为False
会很有帮助 -ENUM.create()
和ENUM.drop()
方法可用于将 SQL 发送到目标绑定。
-
方法
sqlalchemy.dialects.postgresql.ENUM.
create(bind=None, checkfirst=True)¶ 为此
ENUM
发出CREATE TYPE
。如果底层方言不支持 PostgreSQL CREATE TYPE,则不执行任何操作。
- 参数:
bind¶ – 一个可连接的
Engine
、Connection
或类似对象,用于发出 SQL。checkfirst¶ – 如果为
True
,则首先执行针对 PG 目录的查询,以查看该类型是否尚不存在,然后再创建。
-
方法
sqlalchemy.dialects.postgresql.ENUM.
drop(bind=None, checkfirst=True)¶ 为此
ENUM
发出DROP TYPE
。如果底层方言不支持 PostgreSQL DROP TYPE,则不执行任何操作。
- 参数:
bind¶ – 一个可连接的
Engine
、Connection
或类似对象,用于发出 SQL。checkfirst¶ – 如果为
True
,则首先执行针对 PG 目录的查询,以查看该类型是否实际存在,然后再删除。
-
方法
- class sqlalchemy.dialects.postgresql.HSTORE¶
表示 PostgreSQL HSTORE 类型。
HSTORE
类型存储包含字符串的字典,例如:data_table = Table( "data_table", metadata, Column("id", Integer, primary_key=True), Column("data", HSTORE), ) with engine.connect() as conn: conn.execute( data_table.insert(), data={"key1": "value1", "key2": "value2"} )
HSTORE
提供了广泛的操作,包括索引操作
data_table.c.data["some key"] == "some value"
包含操作
data_table.c.data.has_key("some key") data_table.c.data.has_all(["one", "two", "three"])
连接
data_table.c.data + {"k1": "v1"}
有关特殊方法的完整列表,请参见
comparator_factory
。使用 ORM 时检测 HSTORE 列中的更改
对于 SQLAlchemy ORM 的用法,可能需要将
HSTORE
的用法与MutableDict
字典结合使用,该字典现在是sqlalchemy.ext.mutable
扩展的一部分。 此扩展将允许对字典进行“就地”更改,例如向当前字典添加新键或替换/删除现有键,以生成将被工作单元检测到的事件from sqlalchemy.ext.mutable import MutableDict class MyClass(Base): __tablename__ = "data_table" id = Column(Integer, primary_key=True) data = Column(MutableDict.as_mutable(HSTORE)) my_object = session.query(MyClass).one() # in-place mutation, requires Mutable extension # in order for the ORM to detect my_object.data["some_key"] = "some value" session.commit()
当不使用
sqlalchemy.ext.mutable
扩展时,除非将该字典值重新分配给 HSTORE 属性本身,从而生成更改事件,否则 ORM 不会收到现有字典内容发生任何更改的警报。另请参阅
hstore
- 渲染 PostgreSQLhstore()
函数。成员
array(), contained_by(), contains(), defined(), delete(), has_all(), has_any(), has_key(), keys(), matrix(), slice(), vals(), __init__(), bind_processor(), comparator_factory, hashable, result_processor()
类签名
class
sqlalchemy.dialects.postgresql.HSTORE
(sqlalchemy.types.Indexable
,sqlalchemy.types.Concatenable
,sqlalchemy.types.TypeEngine
)- class Comparator¶
定义
HSTORE
的比较操作。类签名
class
sqlalchemy.dialects.postgresql.HSTORE.Comparator
(sqlalchemy.types.Comparator
,sqlalchemy.types.Comparator
)-
方法
sqlalchemy.dialects.postgresql.HSTORE.Comparator.
array()¶ 文本数组表达式。 返回交替键和值的数组。
-
方法
sqlalchemy.dialects.postgresql.HSTORE.Comparator.
contained_by(other)¶ 布尔表达式。 测试键是否是参数 jsonb 表达式的键的真子集。
-
方法
sqlalchemy.dialects.postgresql.HSTORE.Comparator.
contains(other, **kwargs)¶ 布尔表达式。 测试键(或数组)是否是参数 jsonb 表达式的键的超集/包含。
kwargs 可能会被此运算符忽略,但 API 一致性需要它。
-
方法
sqlalchemy.dialects.postgresql.HSTORE.Comparator.
defined(key)¶ 布尔表达式。 测试键是否存在非 NULL 值。 请注意,键可以是 SQLA 表达式。
-
方法
sqlalchemy.dialects.postgresql.HSTORE.Comparator.
delete(key)¶ HStore 表达式。 返回此 hstore 的内容,并删除给定键。 请注意,键可以是 SQLA 表达式。
-
方法
sqlalchemy.dialects.postgresql.HSTORE.Comparator.
has_all(other)¶ 布尔表达式。 测试 jsonb 中是否存在所有键
-
方法
sqlalchemy.dialects.postgresql.HSTORE.Comparator.
has_any(other)¶ 布尔表达式。 测试 jsonb 中是否存在任何键
-
方法
sqlalchemy.dialects.postgresql.HSTORE.Comparator.
has_key(other)¶ 布尔表达式。 测试是否存在键。 请注意,键可以是 SQLA 表达式。
-
方法
sqlalchemy.dialects.postgresql.HSTORE.Comparator.
keys()¶ 文本数组表达式。 返回键的数组。
-
方法
sqlalchemy.dialects.postgresql.HSTORE.Comparator.
matrix()¶ 文本数组表达式。 返回 [键, 值] 对的数组。
-
方法
sqlalchemy.dialects.postgresql.HSTORE.Comparator.
slice(array)¶ HStore 表达式。 返回由键数组定义的 hstore 的子集。
-
方法
sqlalchemy.dialects.postgresql.HSTORE.Comparator.
vals()¶ 文本数组表达式。 返回值的数组。
-
方法
-
方法
sqlalchemy.dialects.postgresql.HSTORE.
__init__(text_type=None)¶ 构造一个新的
HSTORE
。
-
方法
sqlalchemy.dialects.postgresql.HSTORE.
bind_processor(dialect)¶ 返回用于处理绑定值的转换函数。
返回一个可调用对象,它将接收绑定参数值作为唯一的位置参数,并将返回要发送到 DB-API 的值。
如果不需要处理,则该方法应返回
None
。注意
此方法仅相对于方言特定的类型对象调用,该对象通常对方言私有,并且与公共类型对象不同,这意味着为了提供替代的
TypeEngine.bind_processor()
方法,除非显式子类化UserDefinedType
类,否则子类化TypeEngine
类是不可行的。要为
TypeEngine.bind_processor()
提供替代行为,请实现TypeDecorator
类,并提供TypeDecorator.process_bind_param()
的实现。另请参阅
- 参数:
dialect¶ – 使用中的方言实例。
-
attribute
sqlalchemy.dialects.postgresql.HSTORE.
comparator_factory¶ Comparator
的别名
-
attribute
sqlalchemy.dialects.postgresql.HSTORE.
hashable = False¶ 标志,如果为 False,则表示此类型的值不可哈希。
ORM 在对结果列表进行去重时使用。
-
方法
sqlalchemy.dialects.postgresql.HSTORE.
result_processor(dialect, coltype)¶ 返回用于处理结果行值的转换函数。
返回一个可调用对象,它将接收结果行列值作为唯一的位置参数,并将返回要返回给用户的值。
如果不需要处理,则该方法应返回
None
。注意
此方法仅相对于方言特定的类型对象调用,该对象通常对方言私有,并且与公共类型对象不同,这意味着为了提供替代的
TypeEngine.result_processor()
方法,除非显式子类化UserDefinedType
类,否则子类化TypeEngine
类是不可行的。要为
TypeEngine.result_processor()
提供备选行为,请实现TypeDecorator
类,并提供TypeDecorator.process_result_value()
的实现。另请参阅
- class sqlalchemy.dialects.postgresql.INET¶
类签名
class
sqlalchemy.dialects.postgresql.INET
(sqlalchemy.dialects.postgresql.types._NetworkAddressTypeMixin
,sqlalchemy.types.TypeEngine
)
- class sqlalchemy.dialects.postgresql.INTERVAL¶
PostgreSQL INTERVAL 类型。
成员
类签名
class
sqlalchemy.dialects.postgresql.INTERVAL
(sqlalchemy.types.NativeForEmulated
,sqlalchemy.types._AbstractInterval
)-
method
sqlalchemy.dialects.postgresql.INTERVAL.
__init__(precision: int | None = None, fields: str | None = None) → None¶ 构造一个 INTERVAL。
-
method
- class sqlalchemy.dialects.postgresql.JSON¶
表示 PostgreSQL JSON 类型。
JSON
在针对 PostgreSQL 后端使用基本JSON
数据类型时会自动使用,但是基本JSON
数据类型不提供 Python 访问器来访问 PostgreSQL 特定的比较方法,例如Comparator.astext()
;此外,要使用 PostgreSQLJSONB
,应显式使用JSONB
数据类型。另请参阅
JSON
- 通用跨平台 JSON 数据类型的主要文档。PostgreSQL 版本的
JSON
提供的运算符包括索引操作(
->
运算符)data_table.c.data["some key"] data_table.c.data[5]
返回文本的索引操作(
->>
运算符)data_table.c.data["some key"].astext == "some value"
请注意,等效功能可通过
Comparator.as_string
访问器获得。带有 CAST 的索引操作(等效于
CAST(col ->> ['some key'] AS <type>)
)data_table.c.data["some key"].astext.cast(Integer) == 5
请注意,等效功能可通过
Comparator.as_integer
和类似的访问器获得。路径索引操作(
#>
运算符)data_table.c.data[("key_1", "key_2", 5, ..., "key_n")]
返回文本的路径索引操作(
#>>
运算符)data_table.c.data[ ("key_1", "key_2", 5, ..., "key_n") ].astext == "some value"
索引操作返回表达式对象,其类型默认设置为
JSON
,以便可以对结果类型调用进一步的面向 JSON 的指令。自定义序列化器和反序列化器在方言级别指定,即使用
create_engine()
。 这样做的原因是,当使用 psycopg2 时,DBAPI 仅允许在每个游标或每个连接级别进行序列化。例如:engine = create_engine( "postgresql+psycopg2://scott:tiger@localhost/test", json_serializer=my_serialize_fn, json_deserializer=my_deserialize_fn, )
当使用 psycopg2 方言时,json_deserializer 将使用
psycopg2.extras.register_default_json
注册到数据库。- class Comparator¶
定义
JSON
的比较操作。类签名
class
sqlalchemy.dialects.postgresql.JSON.Comparator
(sqlalchemy.types.Comparator
)-
attribute
sqlalchemy.dialects.postgresql.JSON.Comparator.
astext¶ 在索引表达式上,在 SQL 中呈现时使用 “astext”(例如 “->>”)转换。
例如:
select(data_table.c.data["some key"].astext)
另请参阅
-
attribute
-
method
sqlalchemy.dialects.postgresql.JSON.
__init__(none_as_null: bool = False, astext_type: TypeEngine[str] | None = None)¶ 构造一个
JSON
类型。
-
attribute
sqlalchemy.dialects.postgresql.JSON.
comparator_factory¶ Comparator
的别名
-
attribute
sqlalchemy.dialects.postgresql.JSON.
render_bind_cast = True¶ 为
BindTyping.RENDER_CASTS
模式渲染绑定转换。如果为 True,则此类型(通常是方言级别的 impl 类型)向编译器发出信号,表明应在此类型的绑定参数周围呈现转换。
2.0 版本新增。
另请参阅
- class sqlalchemy.dialects.postgresql.JSONB¶
表示 PostgreSQL JSONB 类型。
JSONB
类型存储任意 JSONB 格式的数据,例如:data_table = Table( "data_table", metadata, Column("id", Integer, primary_key=True), Column("data", JSONB), ) with engine.connect() as conn: conn.execute( data_table.insert(), data={"key1": "value1", "key2": "value2"} )
JSONB
类型包含JSON
提供的所有操作,包括索引操作的相同行为。 它还添加了 JSONB 特定的其他运算符,包括Comparator.has_key()
、Comparator.has_all()
、Comparator.has_any()
、Comparator.contains()
、Comparator.contained_by()
、Comparator.delete_path()
、Comparator.path_exists()
和Comparator.path_match()
。与
JSON
类型一样,JSONB
类型在使用 ORM 时不会检测到就地更改,除非使用了sqlalchemy.ext.mutable
扩展。自定义序列化器和反序列化器与
JSON
类共享,使用json_serializer
和json_deserializer
关键字参数。 这些必须在方言级别使用create_engine()
指定。 当使用 psycopg2 时,序列化器使用psycopg2.extras.register_default_jsonb
在每个连接的基础上与 jsonb 类型关联,就像使用psycopg2.extras.register_default_json
将这些处理程序注册到 json 类型一样。另请参阅
成员
contained_by(), contains(), delete_path(), has_all(), has_any(), has_key(), path_exists(), path_match(), comparator_factory
- class Comparator¶
定义
JSON
的比较操作。类签名
class
sqlalchemy.dialects.postgresql.JSONB.Comparator
(sqlalchemy.dialects.postgresql.json.Comparator
)-
method
sqlalchemy.dialects.postgresql.JSONB.Comparator.
contained_by(other: Any) → ColumnElement[bool]¶ 布尔表达式。 测试键是否是参数 jsonb 表达式的键的真子集(等效于
<@
运算符)。
-
method
sqlalchemy.dialects.postgresql.JSONB.Comparator.
contains(other: Any, **kwargs: Any) → ColumnElement[bool]¶ 布尔表达式。 测试键(或数组)是否是参数 jsonb 表达式的键的超集/包含(等效于
@>
运算符)。kwargs 可能会被此运算符忽略,但 API 一致性需要它。
-
method
sqlalchemy.dialects.postgresql.JSONB.Comparator.
delete_path(array: List[str] | _pg_array[str]) → ColumnElement[JSONB]¶ JSONB 表达式。 删除参数数组中指定的字段或数组元素(等效于
#-
运算符)。输入可以是字符串列表(将强制转换为
ARRAY
)或_postgres.array()
的实例。2.0 版本新增。
-
method
sqlalchemy.dialects.postgresql.JSONB.Comparator.
has_all(other: Any) → ColumnElement[bool]¶ 布尔表达式。 测试 jsonb 中是否存在所有键(等效于
?&
运算符)
-
method
sqlalchemy.dialects.postgresql.JSONB.Comparator.
has_any(other: Any) → ColumnElement[bool]¶ 布尔表达式。 测试 jsonb 中是否存在任何键(等效于
?|
运算符)
-
method
sqlalchemy.dialects.postgresql.JSONB.Comparator.
has_key(other: Any) → ColumnElement[bool]¶ 布尔表达式。 测试是否存在键(等效于
?
运算符)。 请注意,键可以是 SQLA 表达式。
-
method
sqlalchemy.dialects.postgresql.JSONB.Comparator.
path_exists(other: Any) → ColumnElement[bool]¶ 布尔表达式。 测试是否存在由参数 JSONPath 表达式给出的项目(等效于
@?
运算符)。2.0 版本新增。
-
method
sqlalchemy.dialects.postgresql.JSONB.Comparator.
path_match(other: Any) → ColumnElement[bool]¶ 布尔表达式。 测试由参数 JSONPath 表达式给出的 JSONPath 谓词是否匹配(等效于
@@
运算符)。仅考虑结果的第一项。
2.0 版本新增。
-
method
-
attribute
sqlalchemy.dialects.postgresql.JSONB.
comparator_factory¶ Comparator
的别名
- class sqlalchemy.dialects.postgresql.JSONPATH¶
JSON Path 类型。
这通常是在使用类似
jsonb_path_query_array
或jsonb_path_exists
这样的 JSON 搜索函数时,将字面值转换为 JSON 路径所必需的。stmt = sa.select( sa.func.jsonb_path_query_array( table.c.jsonb_col, cast("$.address.id", JSONPATH) ) )
类签名
class
sqlalchemy.dialects.postgresql.JSONPATH
(sqlalchemy.dialects.postgresql.json.JSONPathType
)
- class sqlalchemy.dialects.postgresql.MACADDR¶
类签名
class
sqlalchemy.dialects.postgresql.MACADDR
(sqlalchemy.dialects.postgresql.types._NetworkAddressTypeMixin
,sqlalchemy.types.TypeEngine
)
- class sqlalchemy.dialects.postgresql.MACADDR8¶
类签名
class
sqlalchemy.dialects.postgresql.MACADDR8
(sqlalchemy.dialects.postgresql.types._NetworkAddressTypeMixin
,sqlalchemy.types.TypeEngine
)
- class sqlalchemy.dialects.postgresql.MONEY¶
提供 PostgreSQL MONEY 类型。
取决于驱动程序,使用此类型的结果行可能会返回包含货币符号的字符串值。
因此,可能最好使用
TypeDecorator
将其转换为基于数值的货币数据类型import re import decimal from sqlalchemy import Dialect from sqlalchemy import TypeDecorator class NumericMoney(TypeDecorator): impl = MONEY def process_result_value(self, value: Any, dialect: Dialect) -> None: if value is not None: # adjust this for the currency and numeric m = re.match(r"\$([\d.]+)", value) if m: value = decimal.Decimal(m.group(1)) return value
或者,可以使用
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 版本新增。
- class sqlalchemy.dialects.postgresql.OID¶
提供 PostgreSQL OID 类型。
- class sqlalchemy.dialects.postgresql.REAL
SQL REAL 类型。
另请参阅
Float
- 基础类型的文档。类签名
class
sqlalchemy.dialects.postgresql.REAL
(sqlalchemy.types.Float
)-
method
sqlalchemy.dialects.postgresql.REAL.
__init__(precision: int | None = None, asdecimal: bool = False, decimal_return_scale: int | None = None) 继承自
sqlalchemy.types.Float.__init__
方法,源于Float
构造一个 Float 类型。
- 参数:
precision¶ –
用于 DDL
CREATE TABLE
的数值精度。后端应该尝试确保此精度指示通用Float
数据类型的位数。注意
对于 Oracle 数据库后端,渲染 DDL 时不接受
Float.precision
参数,因为 Oracle 数据库不支持以十进制位数指定的浮点精度。请改用 Oracle 数据库特定的FLOAT
数据类型,并指定FLOAT.binary_precision
参数。这是 SQLAlchemy 2.0 版本中的新功能。要创建一个数据库无关的
Float
,该类型为 Oracle 数据库单独指定二进制精度,请使用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 十进制数时使用的默认刻度。 由于十进制不精确性,浮点值通常会更长,并且大多数浮点数据库类型没有“刻度”的概念,因此默认情况下,float 类型在转换时会查找前十位小数位。 指定此值将覆盖该长度。 请注意,MySQL float 类型(确实包含“刻度”)如果未另行指定,则将“刻度”用作 decimal_return_scale 的默认值。
-
method
- class sqlalchemy.dialects.postgresql.REGCONFIG¶
提供 PostgreSQL REGCONFIG 类型。
2.0.0rc1 版本新增。
- class sqlalchemy.dialects.postgresql.REGCLASS¶
提供 PostgreSQL REGCLASS 类型。
1.2.7 版本新增。
- class sqlalchemy.dialects.postgresql.TIMESTAMP¶
提供 PostgreSQL TIMESTAMP 类型。
成员
-
method
sqlalchemy.dialects.postgresql.TIMESTAMP.
__init__(timezone: bool = False, precision: int | None = None) → None¶ 构造一个 TIMESTAMP。
-
method
- class sqlalchemy.dialects.postgresql.TIME¶
PostgreSQL TIME 类型。
成员
-
method
sqlalchemy.dialects.postgresql.TIME.
__init__(timezone: bool = False, precision: int | None = None) → None¶ 构造一个 TIME。
-
method
- class sqlalchemy.dialects.postgresql.TSQUERY¶
提供 PostgreSQL TSQUERY 类型。
2.0.0rc1 版本新增。
- class sqlalchemy.dialects.postgresql.TSVECTOR¶
TSVECTOR
类型实现了 PostgreSQL 文本搜索类型 TSVECTOR。它可用于对自然语言文档执行全文查询。
另请参阅
- class sqlalchemy.dialects.postgresql.UUID
表示 SQL UUID 类型。
这是
Uuid
数据库无关数据类型的 SQL 原生形式,并且向后兼容以前仅限 PostgreSQL 版本的UUID
。UUID
数据类型仅适用于具有名为UUID
的 SQL 数据类型的数据库。 它不适用于没有此精确命名类型的后端,包括 SQL Server。 对于具有原生支持的后端无关 UUID 值,包括 SQL Server 的UNIQUEIDENTIFIER
数据类型,请使用Uuid
数据类型。2.0 版本新增。
另请参阅
类签名
class
sqlalchemy.dialects.postgresql.UUID
(sqlalchemy.types.Uuid
,sqlalchemy.types.NativeForEmulated
)-
method
sqlalchemy.dialects.postgresql.UUID.
__init__(as_uuid: bool = True) 构造一个
UUID
类型。- 参数:
as_uuid=True¶ –
如果为 True,值将被解释为 Python uuid 对象,并通过 DBAPI 在字符串之间进行转换。
-
method
- class sqlalchemy.dialects.postgresql.INT4RANGE¶
表示 PostgreSQL INT4RANGE 类型。
- class sqlalchemy.dialects.postgresql.INT8RANGE¶
表示 PostgreSQL INT8RANGE 类型。
- class sqlalchemy.dialects.postgresql.NUMRANGE¶
表示 PostgreSQL NUMRANGE 类型。
- class sqlalchemy.dialects.postgresql.DATERANGE¶
表示 PostgreSQL DATERANGE 类型。
- class sqlalchemy.dialects.postgresql.TSRANGE¶
表示 PostgreSQL TSRANGE 类型。
- class sqlalchemy.dialects.postgresql.TSTZRANGE¶
表示 PostgreSQL TSTZRANGE 类型。
- class sqlalchemy.dialects.postgresql.INT4MULTIRANGE¶
表示 PostgreSQL INT4MULTIRANGE 类型。
- class sqlalchemy.dialects.postgresql.INT8MULTIRANGE¶
表示 PostgreSQL INT8MULTIRANGE 类型。
- class sqlalchemy.dialects.postgresql.NUMMULTIRANGE¶
表示 PostgreSQL NUMMULTIRANGE 类型。
- class sqlalchemy.dialects.postgresql.DATEMULTIRANGE¶
表示 PostgreSQL DATEMULTIRANGE 类型。
- class sqlalchemy.dialects.postgresql.TSMULTIRANGE¶
表示 PostgreSQL TSRANGE 类型。
- class sqlalchemy.dialects.postgresql.TSTZMULTIRANGE¶
表示 PostgreSQL TSTZRANGE 类型。
- class sqlalchemy.dialects.postgresql.MultiRange¶
表示多范围序列。
此列表子类是一个实用程序,允许根据单范围值自动推断正确的多范围 SQL 类型。 这在操作字面多范围时很有用
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.list
,typing.Generic
)
PostgreSQL SQL 元素和函数¶
对象名称 | 描述 |
---|---|
表示 PostgreSQL 聚合 order by 表达式。 |
|
All(other, arrexpr[, operator]) |
ARRAY 级别的 |
Any(other, arrexpr[, operator]) |
ARRAY 级别的 |
PostgreSQL ARRAY 字面量。 |
|
array_agg(*arg, **kw) |
|
使用 PostgreSQL |
|
PostgreSQL |
|
PostgreSQL |
|
PostgreSQL |
|
PostgreSQL |
|
PostgreSQL |
|
PostgreSQL |
- class 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;
Changed in version 1.2.13: - ORDER BY 参数可以是多个术语
另请参阅
- class sqlalchemy.dialects.postgresql.array¶
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
数据类型。type_
关键字参数传递时,数组的“内部”类型从存在的值推断出来,除非array(["foo", "bar"], type_=CHAR)
多维数组通过嵌套
array
构造产生。 最终ARRAY
类型的维度通过递归添加内部ARRAY
类型的维度来计算stmt = select( array( [array([1, 2]), array([3, 4]), array([column("q"), column("x")])] ) ) print(stmt.compile(dialect=postgresql.dialect()))
产生
SELECT ARRAY[ ARRAY[%(param_1)s, %(param_2)s], ARRAY[%(param_3)s, %(param_4)s], ARRAY[q, x] ] AS anon_1
New in version 1.3.6: 添加了对多维数组字面量的支持
另请参阅
类签名
class
sqlalchemy.dialects.postgresql.array
(sqlalchemy.sql.expression.ExpressionClauseList
)
- function sqlalchemy.dialects.postgresql.array_agg(*arg, **kw)¶
array_agg
的 PostgreSQL 特定形式,确保返回类型为ARRAY
而不是普通的ARRAY
,除非传递了显式的type_
。
- function sqlalchemy.dialects.postgresql.Any(other, arrexpr, operator=<built-in function eq>)¶
ARRAY 级别的
Comparator.any()
方法的同义词。 有关详细信息,请参阅该方法。
- function sqlalchemy.dialects.postgresql.All(other, arrexpr, operator=<built-in function eq>)¶
ARRAY 级别的
Comparator.all()
方法的同义词。 有关详细信息,请参阅该方法。
- class sqlalchemy.dialects.postgresql.hstore¶
使用 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
- PostgreSQLHSTORE
数据类型。成员
-
attribute
sqlalchemy.dialects.postgresql.hstore.
inherit_cache: bool | None = True¶ 指示此
HasCacheKey
实例是否应使用其直接超类使用的缓存键生成方案。该属性默认为
None
,这表示构造尚未考虑它是否适合参与缓存;这在功能上等同于将值设置为False
,但也会发出警告。如果与对象对应的 SQL 不会根据此类的本地属性(而不是其超类)而更改,则可以在特定类上将此标志设置为
True
。另请参阅
为自定义构造启用缓存支持 - 关于为第三方或用户定义的 SQL 构造设置
HasCacheKey.inherit_cache
属性的一般指南。
-
attribute
sqlalchemy.dialects.postgresql.hstore.
type¶ 的别名
HSTORE
-
attribute
- class sqlalchemy.dialects.postgresql.to_tsvector¶
PostgreSQL
to_tsvector
SQL 函数。此函数自动应用 REGCONFIG 参数的类型转换,以使用
REGCONFIG
数据类型,并应用TSVECTOR
的返回类型。假设 PostgreSQL 方言已导入,无论是通过调用
from sqlalchemy.dialects import postgresql
还是通过使用create_engine("postgresql...")
创建 PostgreSQL 引擎,当调用sqlalchemy.func.to_tsvector()
时,将自动使用to_tsvector
,确保在编译和执行时使用正确的参数和返回类型处理程序。2.0.0rc1 版本新增。
类签名
class
sqlalchemy.dialects.postgresql.to_tsvector
(sqlalchemy.dialects.postgresql.ext._regconfig_fn
)
- class sqlalchemy.dialects.postgresql.to_tsquery¶
PostgreSQL
to_tsquery
SQL 函数。此函数自动应用 REGCONFIG 参数的类型转换,以使用
REGCONFIG
数据类型,并应用TSQUERY
的返回类型。假设 PostgreSQL 方言已导入,无论是通过调用
from sqlalchemy.dialects import postgresql
还是通过使用create_engine("postgresql...")
创建 PostgreSQL 引擎,当调用sqlalchemy.func.to_tsquery()
时,将自动使用to_tsquery
,确保在编译和执行时使用正确的参数和返回类型处理程序。2.0.0rc1 版本新增。
类签名
class
sqlalchemy.dialects.postgresql.to_tsquery
(sqlalchemy.dialects.postgresql.ext._regconfig_fn
)
- class sqlalchemy.dialects.postgresql.plainto_tsquery¶
PostgreSQL
plainto_tsquery
SQL 函数。此函数自动应用 REGCONFIG 参数的类型转换,以使用
REGCONFIG
数据类型,并应用TSQUERY
的返回类型。假设 PostgreSQL 方言已导入,无论是通过调用
from sqlalchemy.dialects import postgresql
还是通过使用create_engine("postgresql...")
创建 PostgreSQL 引擎,当调用sqlalchemy.func.plainto_tsquery()
时,将自动使用plainto_tsquery
,确保在编译和执行时使用正确的参数和返回类型处理程序。2.0.0rc1 版本新增。
类签名
class
sqlalchemy.dialects.postgresql.plainto_tsquery
(sqlalchemy.dialects.postgresql.ext._regconfig_fn
)
- class sqlalchemy.dialects.postgresql.phraseto_tsquery¶
PostgreSQL
phraseto_tsquery
SQL 函数。此函数自动应用 REGCONFIG 参数的类型转换,以使用
REGCONFIG
数据类型,并应用TSQUERY
的返回类型。假设 PostgreSQL 方言已导入,无论是通过调用
from sqlalchemy.dialects import postgresql
还是通过使用create_engine("postgresql...")
创建 PostgreSQL 引擎,当调用sqlalchemy.func.phraseto_tsquery()
时,将自动使用phraseto_tsquery
,确保在编译和执行时使用正确的参数和返回类型处理程序。2.0.0rc1 版本新增。
类签名
class
sqlalchemy.dialects.postgresql.phraseto_tsquery
(sqlalchemy.dialects.postgresql.ext._regconfig_fn
)
- class sqlalchemy.dialects.postgresql.websearch_to_tsquery¶
PostgreSQL
websearch_to_tsquery
SQL 函数。此函数自动应用 REGCONFIG 参数的类型转换,以使用
REGCONFIG
数据类型,并应用TSQUERY
的返回类型。假设 PostgreSQL 方言已导入,无论是通过调用
from sqlalchemy.dialects import postgresql
还是通过使用create_engine("postgresql...")
创建 PostgreSQL 引擎,当调用sqlalchemy.func.websearch_to_tsquery()
时,将自动使用websearch_to_tsquery
,确保在编译和执行时使用正确的参数和返回类型处理程序。2.0.0rc1 版本新增。
类签名
class
sqlalchemy.dialects.postgresql.websearch_to_tsquery
(sqlalchemy.dialects.postgresql.ext._regconfig_fn
)
- class sqlalchemy.dialects.postgresql.ts_headline¶
PostgreSQL
ts_headline
SQL 函数。此函数自动应用 REGCONFIG 参数的类型转换,以使用
REGCONFIG
数据类型,并应用TEXT
的返回类型。假设 PostgreSQL 方言已导入,无论是通过调用
from sqlalchemy.dialects import postgresql
还是通过使用create_engine("postgresql...")
创建 PostgreSQL 引擎,当调用sqlalchemy.func.ts_headline()
时,将自动使用ts_headline
,确保在编译和执行时使用正确的参数和返回类型处理程序。2.0.0rc1 版本新增。
类签名
class
sqlalchemy.dialects.postgresql.ts_headline
(sqlalchemy.dialects.postgresql.ext._regconfig_fn
)
PostgreSQL 约束类型¶
SQLAlchemy 通过 ExcludeConstraint
类支持 PostgreSQL EXCLUDE 约束
对象名称 | 描述 |
---|---|
表级别的 EXCLUDE 约束。 |
- class sqlalchemy.dialects.postgresql.ExcludeConstraint¶
表级别的 EXCLUDE 约束。
定义 EXCLUDE 约束,如 PostgreSQL 文档中所述。
成员
类签名
class
sqlalchemy.dialects.postgresql.ExcludeConstraint
(sqlalchemy.schema.ColumnCollectionConstraint
)-
method
sqlalchemy.dialects.postgresql.ExcludeConstraint.
__init__(*elements, **kw)¶ 创建
ExcludeConstraint
对象。例如:
const = ExcludeConstraint( (Column("period"), "&&"), (Column("group"), "="), where=(Column("group") != "some group"), ops={"group": "my_operator_class"}, )
该约束通常直接嵌入到
Table
构造中,或稍后使用append_constraint()
添加some_table = Table( "some_table", metadata, Column("id", Integer, primary_key=True), Column("period", TSRANGE()), Column("group", String), ) some_table.append_constraint( ExcludeConstraint( (some_table.c.period, "&&"), (some_table.c.group, "="), where=some_table.c.group != "some group", name="some_table_excl_const", ops={"group": "my_operator_class"}, ) )
此示例中定义的排除约束需要
btree_gist
扩展,可以使用命令CREATE EXTENSION btree_gist;
创建。- 参数:
*elements¶ –
两个元组的序列,形式为
(column, operator)
,其中 “column” 是Column
对象,或 SQL 表达式元素(例如func.int8range(table.from, table.to)
),或列的名称(字符串),“operator” 是包含要使用的运算符的字符串(例如 “&&” 或 “=”)。为了在
Column
对象不可用时指定列名,同时确保任何必要的引用规则生效,应使用临时的Column
或column()
对象。column
也可以是作为literal_column()
或text()
传递的字符串 SQL 表达式name¶ – 可选,此约束在数据库中的名称。
deferrable¶ – 可选布尔值。如果设置,则在为此约束发出 DDL 时发出 DEFERRABLE 或 NOT DEFERRABLE。
initially¶ – 可选字符串。如果设置,则在为此约束发出 DDL 时发出 INITIALLY <value>。
using¶ – 可选字符串。如果设置,则在为此约束发出 DDL 时发出 USING <index_method>。默认为 ‘gist’。
where¶ –
可选的 SQL 表达式构造或字面 SQL 字符串。如果设置,则在为此约束发出 DDL 时发出 WHERE <predicate>。
警告
可以将
ExcludeConstraint.where
参数作为 Python 字符串参数传递给ExcludeConstraint
,该参数将被视为 受信任的 SQL 文本 并按给定方式呈现。请勿将不受信任的输入传递给此参数。ops¶ –
可选字典。用于为元素定义运算符类;其工作方式与为
Index
构造指定的 postgresql_ops 参数相同。1.3.21 版本新增。
另请参阅
运算符类 - 关于如何指定 PostgreSQL 运算符类的一般描述。
-
method
例如
from sqlalchemy.dialects.postgresql import ExcludeConstraint, TSRANGE
class RoomBooking(Base):
__tablename__ = "room_booking"
room = Column(Integer(), primary_key=True)
during = Column(TSRANGE())
__table_args__ = (ExcludeConstraint(("room", "="), ("during", "&&")),)
PostgreSQL DML 构造¶
对象名称 | 描述 |
---|---|
insert(table) |
构造一个 PostgreSQL 特定的变体 |
PostgreSQL 特定的 INSERT 实现。 |
- function sqlalchemy.dialects.postgresql.insert(table: _DMLTableArgument) → Insert¶
构造一个 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()
。
- class sqlalchemy.dialects.postgresql.Insert¶
PostgreSQL 特定的 INSERT 实现。
为 PG 特定的语法(例如 ON CONFLICT)添加方法。
Insert
对象是使用sqlalchemy.dialects.postgresql.insert()
函数创建的。-
attribute
sqlalchemy.dialects.postgresql.Insert.
excluded¶ 为 ON CONFLICT 语句提供
excluded
命名空间PG 的 ON CONFLICT 子句允许引用将要插入的行,称为
excluded
。此属性提供此行中的所有列以供引用。提示
Insert.excluded
属性是ColumnCollection
的实例,它提供的接口与Table.c
集合相同,如 访问表和列 中所述。 使用此集合,普通名称可以像属性一样访问(例如stmt.excluded.some_column
),但特殊名称和字典方法名称应使用索引访问来访问,例如stmt.excluded["column name"]
或stmt.excluded["values"]
。 有关更多示例,请参阅ColumnCollection
的文档字符串。另请参阅
INSERT…ON CONFLICT (Upsert) - 如何使用
Insert.excluded
的示例
-
attribute
sqlalchemy.dialects.postgresql.Insert.
inherit_cache: bool | None = False¶ 指示此
HasCacheKey
实例是否应使用其直接超类使用的缓存键生成方案。该属性默认为
None
,这表示构造尚未考虑它是否适合参与缓存;这在功能上等同于将值设置为False
,但也会发出警告。如果与对象对应的 SQL 不会根据此类的本地属性(而不是其超类)而更改,则可以在特定类上将此标志设置为
True
。另请参阅
为自定义构造启用缓存支持 - 关于为第三方或用户定义的 SQL 构造设置
HasCacheKey.inherit_cache
属性的一般指南。
-
method
sqlalchemy.dialects.postgresql.Insert.
on_conflict_do_nothing(constraint: str | ColumnCollectionConstraint | Index | None = None, index_elements: Iterable[Column[Any] | str | DDLConstraintColumnRole] | None = None, index_where: WhereHavingRole | None = None) → Self¶ 为 ON CONFLICT 子句指定 DO NOTHING 操作。
constraint
和index_elements
参数是可选的,但只能指定其中一个。
-
method
sqlalchemy.dialects.postgresql.Insert.
on_conflict_do_update(constraint: str | ColumnCollectionConstraint | Index | None = None, index_elements: Iterable[Column[Any] | str | DDLConstraintColumnRole] | None = None, index_where: WhereHavingRole | None = None, set_: Mapping[Any, Any] | ColumnCollection[Any, Any] | None = None, where: WhereHavingRole | None = None) → Self¶ 为 ON CONFLICT 子句指定 DO UPDATE SET 操作。
constraint
或index_elements
参数是必需的,但只能指定其中一个。- 参数:
constraint¶ – 表上唯一约束或排除约束的名称,或者如果约束对象具有 .name 属性,则为约束对象本身。
index_elements¶ – 由字符串列名、
Column
对象或其他列表达式对象组成的序列,这些对象将用于推断目标索引。index_where¶ – 可用于推断条件目标索引的附加 WHERE 条件。
set_¶ –
一个字典或其他映射对象,其中键是目标表中列的名称,或者是
Column
对象或其他与目标表匹配的 ORM 映射列,值是表达式或字面量,指定要执行的SET
操作。1.4 版本新增:
Insert.on_conflict_do_update.set_
参数支持来自目标Table
的Column
对象作为键。警告
此字典不考虑 Python 指定的默认 UPDATE 值或生成函数,例如使用
Column.onupdate
指定的值。这些值不会为 ON CONFLICT 样式的 UPDATE 执行,除非它们在Insert.on_conflict_do_update.set_
字典中手动指定。where¶ – 可选参数。表示
WHERE
子句的表达式对象,该子句限制受DO UPDATE SET
影响的行。不满足WHERE
条件的行将不会被更新(实际上对于这些行是DO NOTHING
)。
-
attribute
psycopg2¶
通过 psycopg2 驱动程序支持 PostgreSQL 数据库。
DBAPI¶
psycopg2 的文档和下载信息(如果适用)可在以下网址获取:https://pypi.ac.cn/project/psycopg2/
连接¶
连接字符串
postgresql+psycopg2://user:password@host:port/dbname[?key=value&key=value...]
psycopg2 连接参数¶
SQLAlchemy psycopg2 方言特有的关键字参数可以传递给 create_engine()
,包括以下内容
isolation_level
:此选项适用于所有 PostgreSQL 方言,在使用 psycopg2 方言时包括AUTOCOMMIT
隔离级别。此选项设置连接的默认隔离级别,该级别在连接到数据库后立即设置,然后在连接被池化之前设置。此选项通常被更现代的Connection.execution_options.isolation_level
执行选项取代,详细信息请参见 设置事务隔离级别,包括 DBAPI 自动提交。client_encoding
:以 libpq 不可知的方式设置客户端编码,使用 psycopg2 的set_client_encoding()
方法。另请参阅
executemany_mode
、executemany_batch_page_size
、executemany_values_page_size
:允许使用 psycopg2 扩展来优化 “executemany” 风格的查询。有关详细信息,请参阅下面引用的部分。另请参阅
提示
上面的关键字参数是方言关键字参数,这意味着它们作为显式关键字参数传递给 create_engine()
engine = create_engine(
"postgresql+psycopg2://scott:tiger@localhost/test",
isolation_level="SERIALIZABLE",
)
这些不应与 DBAPI 连接参数混淆,DBAPI 连接参数作为 create_engine.connect_args
字典的一部分传递,和/或在 URL 查询字符串中传递,如 自定义 DBAPI connect() 参数 / 连接时例程 部分所述。
SSL 连接¶
psycopg2 模块有一个名为 sslmode
的连接参数,用于控制其关于安全 (SSL) 连接的行为。默认值为 sslmode=prefer
;它将尝试 SSL 连接,如果失败,则回退到未加密的连接。sslmode=require
可用于确保仅建立安全连接。有关更多可用选项,请查阅 psycopg2 / libpq 文档。
请注意,sslmode
是 psycopg2 特有的,因此它包含在连接 URI 中
engine = sa.create_engine(
"postgresql+psycopg2://scott:tiger@192.168.0.199:5432/test?sslmode=require"
)
Unix 域连接¶
psycopg2 支持通过 Unix 域连接进行连接。当 URL 的 host
部分被省略时,SQLAlchemy 将 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 等工具为此硬编码了两个主机名。
另请参阅
指定多个备用主机¶
psycopg2 在连接字符串中支持多个连接点。当 host
参数在 URL 的查询部分中多次使用时,SQLAlchemy 将创建一个包含提供的主机和端口信息的单个字符串以进行连接。令牌可以包含 host::port
或仅 host
;在后一种情况下,默认端口由 libpq 选择。在下面的示例中,指定了三个主机连接,分别用于 HostA::PortA
、连接到默认端口的 HostB
和 HostC::PortC
create_engine(
"postgresql+psycopg2://user:password@/dbname?host=HostA:PortA&host=HostB&host=HostC:PortC"
)
作为替代方案,也可以使用 libpq 查询字符串格式;这会将 host
和 port
指定为带有逗号分隔列表的单个查询字符串参数 - 可以通过在逗号分隔列表中指示空值来选择默认端口
create_engine(
"postgresql+psycopg2://user:password@/dbname?host=HostA,HostB,HostC&port=PortA,,PortC"
)
使用任一 URL 样式,都会根据可配置的策略尝试连接到每个主机,该策略可以使用 libpq target_session_attrs
参数进行配置。根据 libpq,这默认为 any
,表示然后尝试连接到每个主机,直到连接成功。其他策略包括 primary
、prefer-standby
等。PostgreSQL 在 libpq 连接字符串 中记录了完整列表。
例如,要使用 primary
策略指示两个主机
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 的无参数连接。
另请参阅
环境变量 - PostgreSQL 文档,介绍如何使用 PG_...
环境变量进行连接。
每个语句/连接的执行选项¶
以下 DBAPI 特定的选项在使用 Connection.execution_options()
、Executable.execution_options()
、Query.execution_options()
时被遵循,除了那些不特定于 DBAPI 的选项之外
isolation_level
- 设置Connection
生命周期内的事务隔离级别(只能在连接上设置,不能在语句或查询上设置)。请参阅 Psycopg2 事务隔离级别。stream_results
- 启用或禁用 psycopg2 服务器端游标的使用 - 此功能使用 “命名” 游标与特殊结果处理方法相结合,以便结果行不会被完全缓冲。默认为 False,这意味着默认情况下游标会被缓冲。max_row_buffer
- 当使用stream_results
时,一个整数值,指定一次要缓冲的最大行数。这由BufferedRowCursorResult
解释,如果省略,缓冲区将增长到最终一次存储 1000 行。1.4 版本更改:
max_row_buffer
大小现在可以大于 1000,并且缓冲区将增长到该大小。
Psycopg2 快速执行助手¶
现代版本的 psycopg2 包括一个名为 快速执行助手 的功能,在基准测试中已证明可以提高 psycopg2 的 executemany() 性能,主要是在 INSERT 语句中,至少提高一个数量级。
SQLAlchemy 实现了 “插入多个值” 处理程序的本机形式,它将重写单行 INSERT 语句,以便在一个扩展的 VALUES 子句中容纳多个值;此处理程序等效于 psycopg2 的 execute_values()
处理程序;有关此功能及其配置的概述,请参阅 INSERT 语句的 “插入多个值” 行为。
2.0 版本新增: 将 psycopg2 的 execute_values()
快速执行助手替换为名为 insertmanyvalues 的本机 SQLAlchemy 机制。
psycopg2 方言保留了使用 psycopg2 特定的 execute_batch()
功能的能力,尽管预计这不是一个广泛使用的功能。可以使用 executemany_mode
标志启用此扩展的使用,该标志可以传递给 create_engine()
engine = create_engine(
"postgresql+psycopg2://scott:tiger@host/dbname",
executemany_mode="values_plus_batch",
)
executemany_mode
的可能选项包括
values_only
- 这是默认值。SQLAlchemy 的本机 insertmanyvalues 处理程序用于限定 INSERT 语句,假设create_engine.use_insertmanyvalues
保留其默认值True
。此处理程序重写简单的 INSERT 语句以包含多个 VALUES 子句,以便可以使用一个语句插入多个参数集。'values_plus_batch'
- SQLAlchemy 的本机 insertmanyvalues 处理程序用于限定 INSERT 语句,假设create_engine.use_insertmanyvalues
保留其默认值True
。然后,psycopg2 的execute_batch()
处理程序用于在使用多个参数集执行时限定 UPDATE 和 DELETE 语句。当使用此模式时,CursorResult.rowcount
属性将不包含针对 UPDATE 和 DELETE 语句的 executemany 样式执行的值。
2.0 版本更改: 从 psycopg2 executemany_mode
中删除了 'batch'
和 'None'
选项。现在通过 create_engine.use_insertmanyvalues
引擎级参数配置 INSERT 语句的批处理控制。
术语 “限定语句” 是指正在执行的语句是 Core insert()
、update()
或 delete()
构造,而不是纯文本 SQL 字符串或使用 text()
构造的字符串。它也不能是特殊的 “扩展” 语句,例如 “ON CONFLICT” “upsert” 语句。当使用 ORM 时,ORM 刷新过程使用的所有 insert/update/delete 语句都是限定的。
psycopg2 “batch” 策略的 “页面大小” 可以通过使用 executemany_batch_page_size
参数来影响,该参数默认为 100。
对于 “insertmanyvalues” 功能,可以使用 create_engine.insertmanyvalues_page_size
参数来控制页面大小,该参数默认为 1000。下面是修改这两个参数的示例
engine = create_engine(
"postgresql+psycopg2://scott:tiger@host/dbname",
executemany_mode="values_plus_batch",
insertmanyvalues_page_size=5000,
executemany_batch_page_size=500,
)
另请参阅
INSERT 语句的 “插入多个值” 行为 - 关于 “insertmanyvalues” 的背景信息
发送多个参数 - 关于使用 Connection
对象以使其能够使用 DBAPI .executemany()
方法的方式执行语句的一般信息。
Psycopg2 的 Unicode 支持¶
psycopg2 DBAPI 驱动程序透明地支持 Unicode 数据。
可以按照以下方式控制 psycopg2 方言的客户端字符编码
对于 PostgreSQL 9.1 及更高版本,可以在数据库 URL 中传递
client_encoding
参数;此参数由底层libpq
PostgreSQL 客户端库使用engine = create_engine( "postgresql+psycopg2://user:pass@host/dbname?client_encoding=utf8" )
或者,可以使用
create_engine.connect_args
传递上述client_encoding
值,以便与libpq
建立程序化连接engine = create_engine( "postgresql+psycopg2://user:pass@host/dbname", connect_args={"client_encoding": "utf8"}, )
对于所有 PostgreSQL 版本,psycopg2 支持客户端编码值,该值将在首次建立数据库连接时传递给数据库连接。SQLAlchemy psycopg2 方言支持使用传递给
create_engine()
的client_encoding
参数来实现此目的engine = create_engine( "postgresql+psycopg2://user:pass@host/dbname", client_encoding="utf8" )
提示
上述
client_encoding
参数在外观上与在create_engine.connect_args
字典中使用该参数非常相似;上面的区别在于该参数由 psycopg2 使用,并使用SET client_encoding TO 'utf8'
传递到数据库连接;在前面提到的样式中,该参数而是通过 psycopg2 传递并由libpq
库使用。设置 PostgreSQL 数据库客户端编码的常用方法是确保在服务器端的 postgresql.conf 文件中配置它;这是为所有数据库编码一致的服务器设置编码的推荐方法。
# postgresql.conf file # client_encoding = sql_ascii # actually, defaults to database # encoding client_encoding = utf8
事务¶
psycopg2 方言完全支持 SAVEPOINT 和两阶段提交操作。
Psycopg2 事务隔离级别¶
正如在事务隔离级别中讨论的那样,所有 PostgreSQL 方言都支持通过传递给 create_engine()
的 isolation_level
参数以及 Connection.execution_options()
使用的 isolation_level
参数来设置事务隔离级别。当使用 psycopg2 方言时,这些选项使用 psycopg2 的 set_isolation_level()
连接方法,而不是发出 PostgreSQL 指令;这是因为无论如何,psycopg2 的 API 级别设置始终在每个事务开始时发出。
psycopg2 方言支持以下隔离级别常量
READ COMMITTED
READ UNCOMMITTED
REPEATABLE READ
SERIALIZABLE
AUTOCOMMIT
NOTICE 日志记录¶
psycopg2 方言将通过 sqlalchemy.dialects.postgresql
logger 记录 PostgreSQL NOTICE 消息。当此 logger 设置为 logging.INFO
级别时,将记录 notice 消息
import logging
logging.getLogger("sqlalchemy.dialects.postgresql").setLevel(logging.INFO)
上面假设日志记录是在外部配置的。如果不是这种情况,则必须使用诸如 logging.basicConfig()
之类的配置
import logging
logging.basicConfig() # log messages to stdout
logging.getLogger("sqlalchemy.dialects.postgresql").setLevel(logging.INFO)
另请参阅
Logging HOWTO - 在 python.org 网站上
HSTORE 类型¶
psycopg2
DBAPI 包括一个扩展,用于本地处理 HSTORE 类型的编组。当使用 psycopg2 版本 2.4 或更高版本,并且检测到目标数据库已设置 HSTORE 类型以供使用时,SQLAlchemy psycopg2 方言将默认启用此扩展。换句话说,当方言建立第一个连接时,会执行如下序列:
使用
psycopg2.extras.HstoreAdapter.get_oids()
请求可用的 HSTORE oids。如果此函数返回 HSTORE 标识符列表,则我们确定HSTORE
扩展存在。如果安装的 psycopg2 版本低于 2.4,则会跳过此函数。如果
use_native_hstore
标志处于其默认值True
,并且我们已检测到HSTORE
oids 可用,则将为所有连接调用psycopg2.extensions.register_hstore()
扩展。
register_hstore()
扩展的效果是所有 Python 字典都被接受为参数,而不管 SQL 中目标列的类型如何。字典由此扩展转换为文本 HSTORE 表达式。如果不需要此行为,请通过将 use_native_hstore
设置为 False
来禁用 hstore 扩展,如下所示:
engine = create_engine(
"postgresql+psycopg2://scott:tiger@localhost/test",
use_native_hstore=False,
)
当不使用 psycopg2.extensions.register_hstore()
扩展时,仍然支持 HSTORE
类型。这仅仅意味着 Python 字典和 HSTORE 字符串格式之间的强制转换(在参数侧和结果侧)将在 SQLAlchemy 自己的编组逻辑中进行,而不是在可能性能更高的 psycopg2
中进行。
psycopg¶
通过 psycopg(又名 psycopg 3)驱动程序支持 PostgreSQL 数据库。
DBAPI¶
psycopg(又名 psycopg 3)的文档和下载信息(如果适用)可在以下网址获得:https://pypi.ac.cn/project/psycopg/
连接¶
连接字符串
postgresql+psycopg://user:password@host:port/dbname[?key=value&key=value...]
psycopg
是 psycopg
数据库驱动程序版本 3 的包和模块名称,以前称为 psycopg2
。此驱动程序与其 psycopg2
前身有很大不同,因此 SQLAlchemy 通过完全独立的方言支持它;对于 psycopg2
的支持预计将持续存在,只要该包继续为现代 Python 版本工作,并且仍然是 postgresql://
方言系列的默认方言。
SQLAlchemy psycopg
方言在同一方言名称下提供同步和异步实现。根据引擎的创建方式选择正确的版本
使用
postgresql+psycopg://...
调用create_engine()
将自动选择同步版本,例如:from sqlalchemy import create_engine sync_engine = create_engine( "postgresql+psycopg://scott:tiger@localhost/test" )
使用
postgresql+psycopg://...
调用create_async_engine()
将自动选择异步版本,例如:from sqlalchemy.ext.asyncio import create_async_engine asyncio_engine = create_async_engine( "postgresql+psycopg://scott:tiger@localhost/test" )
异步版本的方言也可以使用 psycopg_async
后缀显式指定,如下所示:
from sqlalchemy.ext.asyncio import create_async_engine
asyncio_engine = create_async_engine(
"postgresql+psycopg_async://scott:tiger@localhost/test"
)
另请参阅
psycopg2 - SQLAlchemy psycopg
方言与其 psycopg2
方言共享大部分行为。更多文档可在此处找到。
使用不同的 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 数据库。
DBAPI¶
pg8000 的文档和下载信息(如果适用)可在以下网址获得:https://pypi.ac.cn/project/pg8000/
连接¶
连接字符串
postgresql+pg8000://user:password@host:port/dbname[?key=value&key=value...]
在 1.4 版本中更改:pg8000 方言已更新至 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 将基于传递给 create_engine()
的 client_encoding
参数的值,在所有新连接上执行此 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 方言相同的隔离级别设置。
READ COMMITTED
READ UNCOMMITTED
REPEATABLE READ
SERIALIZABLE
AUTOCOMMIT
asyncpg¶
通过 asyncpg 驱动程序支持 PostgreSQL 数据库。
DBAPI¶
asyncpg 的文档和下载信息(如果适用)可在以下网址获得:https://magicstack.github.io/asyncpg/
连接¶
连接字符串
postgresql+asyncpg://user:password@host:port/dbname[?key=value&key=value...]
asyncpg 方言是 SQLAlchemy 的第一个 Python asyncio 方言。
asyncpg 方言使用特殊的 asyncio 中介层,可以用作 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 不解码 json
和 jsonb
类型,而是将它们作为字符串返回。SQLAlchemy 为 json
和 jsonb
类型设置默认类型解码器,使用 python 内置的 json.loads
函数。可以通过在使用 create_engine()
或 create_async_engine()
创建引擎时设置属性 json_deserializer
来更改使用的 json 实现。
多主机连接¶
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()
。预处理语句对象在构造后会被缓存,这似乎为语句调用带来了 10% 或更高的性能提升。缓存是基于每个 DBAPI 连接的,这意味着预处理语句的主要存储在连接池中池化的 DBAPI 连接中。此缓存的大小默认为每个 DBAPI 连接 100 个语句,可以使用 prepared_statement_cache_size
DBAPI 参数进行调整(请注意,虽然此参数由 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
对象)时,这些缓存会变得陈旧。此外,SQLAlchemy 的驱动程序可选缓存的预处理语句本身,当已向 PostgreSQL 数据库发出 DDL 以修改特定预处理语句中涉及的表或其他对象时,也可能变得“陈旧”。
当代表 DDL 的语句在本地连接上发出时,SQLAlchemy asyncpg 方言将在其本地进程中使这些缓存失效,但这仅在单个 Python 进程/数据库引擎中可控。如果 DDL 更改是从其他数据库引擎和/或进程进行的,则运行中的应用程序可能会遇到 asyncpg 异常 InvalidCachedStatementError
和/或 InternalServerError("cache lookup failed for type <oid>")
,如果它引用了对先前结构进行操作的池化数据库连接。当驱动程序引发这些异常时,SQLAlchemy asyncpg 方言将通过清除其内部缓存以及 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()}__",
},
)
禁用 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 数据库。
DBAPI¶
psycopg2cffi 的文档和下载信息(如果适用)可在以下网址获得:https://pypi.ac.cn/project/psycopg2cffi/
连接¶
连接字符串
postgresql+psycopg2cffi://user:password@host:port/dbname[?key=value&key=value...]
psycopg2cffi
是 psycopg2
的改编版本,使用 CFFI 作为 C 层。这使其适用于例如 PyPy。文档与 psycopg2
相同。
flambé! 龙和 The Alchemist 图像设计由 Rotem Yaari 创建并慷慨捐赠。
使用 Sphinx 7.2.6 创建。文档上次生成时间:2025 年 3 月 11 日星期二下午 02:40:17 EDT