SQLAlchemy 2.0 文档
操作符参考¶
本节详细介绍了可用于构建 SQL 表达式的操作符的使用方法。
这些方法以 Operators
和 ColumnOperators
基类表示。这些方法在这些类的子类中可用,包括
Column
对象ColumnElement
对象,更一般地说,它们是所有 Core SQL 表达式语言列级表达式的根InstrumentedAttribute
对象,它们是 ORM 级别的映射属性。
这些操作符首先在教程部分介绍,包括
SQLAlchemy 统一教程 - 2.0 风格 的统一教程
SQL 表达式语言教程 - 1.x 风格 的 Core 教程
比较操作符¶
适用于许多数据类型的基本比较,包括数值、字符串、日期和许多其他类型
ColumnOperators.__eq__()
(Python 的 “==
” 运算符)>>> print(column("x") == 5)
x = :x_1ColumnOperators.__ne__()
(Python 的 “!=
” 运算符)>>> print(column("x") != 5)
x != :x_1ColumnOperators.__gt__()
(Python 的 “>
” 运算符)>>> print(column("x") > 5)
x > :x_1ColumnOperators.__lt__()
(Python 的 “<
” 运算符)>>> print(column("x") < 5)
x < :x_1ColumnOperators.__ge__()
(Python 的 “>=
” 运算符)>>> print(column("x") >= 5)
x >= :x_1ColumnOperators.__le__()
(Python 的 “<=
” 运算符)>>> print(column("x") <= 5)
x <= :x_1-
>>> print(column("x").between(5, 10))
x BETWEEN :x_1 AND :x_2
IN 比较¶
SQL 的 IN 操作符在 SQLAlchemy 中是一个独立的主题。由于 IN 操作符通常针对固定值的列表使用,所以 SQLAlchemy 的绑定参数强制转换功能使用了一种特殊的 SQL 编译形式,该形式在编译时生成一个中间 SQL 字符串,该字符串在第二步中被转换为最终的绑定参数列表。换句话说,“它只是有效”。
对值列表进行 IN 比较¶
IN 通常通过将值列表传递给 ColumnOperators.in_()
方法来使用。
>>> print(column("x").in_([1, 2, 3]))
x IN (__[POSTCOMPILE_x_1])
特殊的绑定形式 __[POSTCOMPILE
会在执行时渲染为单个参数,如下所示。
>>> stmt = select(User.id).where(User.id.in_([1, 2, 3]))
>>> result = conn.execute(stmt)
SELECT user_account.id
FROM user_account
WHERE user_account.id IN (?, ?, ?)
[...] (1, 2, 3)
空 IN 表达式¶
SQLAlchemy 通过渲染一个返回没有行的特定于后端的子查询来生成一个数学上有效的空 IN 表达式的结果。同样,换句话说,“它只是有效”。
>>> stmt = select(User.id).where(User.id.in_([]))
>>> result = conn.execute(stmt)
SELECT user_account.id
FROM user_account
WHERE user_account.id IN (SELECT 1 FROM (SELECT 1) WHERE 1!=1)
[...] ()
上面的“空集”子查询正确地概括了,并且也根据 IN 操作符渲染,该操作符仍然保留在位。
NOT IN¶
“NOT IN” 通过 ColumnOperators.not_in()
操作符提供。
>>> print(column("x").not_in([1, 2, 3]))
(x NOT IN (__[POSTCOMPILE_x_1]))
这通常可以通过对 ~
运算符进行否定来更容易地获得。
>>> print(~column("x").in_([1, 2, 3]))
(x NOT IN (__[POSTCOMPILE_x_1]))
元组 IN 表达式¶
元组与元组的比较在 IN 中很常见,因为它除了其他用例外,还可以适应将行与一组可能的复合主键值进行匹配的情况。 tuple_()
构造提供了元组比较的基本构建块。然后,Tuple.in_()
操作符接收一个元组列表。
>>> from sqlalchemy import tuple_
>>> tup = tuple_(column("x", Integer), column("y", Integer))
>>> expr = tup.in_([(1, 2), (3, 4)])
>>> print(expr)
(x, y) IN (__[POSTCOMPILE_param_1])
为了说明渲染的参数。
>>> tup = tuple_(User.id, Address.id)
>>> stmt = select(User.name).join(Address).where(tup.in_([(1, 1), (2, 2)]))
>>> conn.execute(stmt).all()
SELECT user_account.name
FROM user_account JOIN address ON user_account.id = address.user_id
WHERE (user_account.id, address.id) IN (VALUES (?, ?), (?, ?))
[...] (1, 1, 2, 2)
[('spongebob',), ('sandy',)]
子查询 IN¶
最后,ColumnOperators.in_()
和 ColumnOperators.not_in()
操作符适用于子查询。该形式规定直接传递一个 Select
构造,无需将其显式转换为命名子查询。
>>> print(column("x").in_(select(user_table.c.id)))
x IN (SELECT user_account.id
FROM user_account)
元组按预期工作。
>>> print(
... tuple_(column("x"), column("y")).in_(
... select(user_table.c.id, address_table.c.id).join(address_table)
... )
... )
(x, y) IN (SELECT user_account.id, address.id
FROM user_account JOIN address ON user_account.id = address.user_id)
身份比较¶
这些操作符涉及测试特殊的 SQL 值,例如 NULL
、布尔常量,例如 true
或 false
,某些数据库支持这些值。
-
此操作符将提供 “x IS y” 的 SQL,最常被看作是 “<expr> IS NULL”。
NULL
常量通常使用 Python 的None
获取。>>> print(column("x").is_(None))
x IS NULL如果需要,可以使用
null()
构造显式地获取 SQL NULL。>>> from sqlalchemy import null >>> print(column("x").is_(null()))
x IS NULL当与
None
或null()
值一起使用时,ColumnOperators.is_()
操作符会自动调用,即ColumnOperators.__eq__()
重载运算符,即==
。这样,通常不需要显式使用ColumnOperators.is_()
,特别是当与动态值一起使用时。>>> a = None >>> print(column("x") == a)
x IS NULL请注意,Python 的
is
运算符**没有重载**。即使 Python 提供了重载运算符(如==
和!=
)的钩子,它**也不**提供任何重新定义is
的方法。 -
类似于
ColumnOperators.is_()
,生成“IS NOT”>>> print(column("x").is_not(None))
x IS NOT NULL类似于
!= None
>>> print(column("x") != None)
x IS NOT NULL ColumnOperators.is_distinct_from()
:生成 SQL IS DISTINCT FROM
>>> print(column("x").is_distinct_from("some value"))
x IS DISTINCT FROM :x_1ColumnOperators.isnot_distinct_from()
:生成 SQL IS NOT DISTINCT FROM
>>> print(column("x").isnot_distinct_from("some value"))
x IS NOT DISTINCT FROM :x_1
字符串比较¶
-
>>> print(column("x").like("word"))
x LIKE :x_1 -
不区分大小写的 LIKE 在通用后端上使用 SQL
lower()
函数。在 PostgreSQL 后端,它将使用ILIKE
>>> print(column("x").ilike("word"))
lower(x) LIKE lower(:x_1) -
>>> print(column("x").notlike("word"))
x NOT LIKE :x_1 -
>>> print(column("x").notilike("word"))
lower(x) NOT LIKE lower(:x_1)
字符串包含¶
字符串包含运算符基本上是作为 LIKE 和字符串连接运算符的组合构建的,在大多数后端上是 ||
,或者有时是像 concat()
这样的函数
-
>>> print(column("x").startswith("word"))
x LIKE :x_1 || '%' -
>>> print(column("x").endswith("word"))
x LIKE '%' || :x_1 -
>>> print(column("x").contains("word"))
x LIKE '%' || :x_1 || '%'
字符串匹配¶
匹配运算符总是特定于后端的,并且可能在不同的数据库上提供不同的行为和结果
-
这是一个特定于方言的运算符,它使用底层数据库(如果可用)的 MATCH 功能
>>> print(column("x").match("word"))
x MATCH :x_1 ColumnOperators.regexp_match()
:此运算符特定于方言。我们可以用 PostgreSQL 方言为例来说明它
>>> from sqlalchemy.dialects import postgresql >>> print(column("x").regexp_match("word").compile(dialect=postgresql.dialect()))
x ~ %(x_1)s或 MySQL
>>> from sqlalchemy.dialects import mysql >>> print(column("x").regexp_match("word").compile(dialect=mysql.dialect()))
x REGEXP %s
字符串修改¶
-
字符串连接
>>> print(column("x").concat("some string"))
x || :x_1此运算符可通过
ColumnOperators.__add__()
获得,即在处理从String
派生的列表达式时使用 Python+
运算符。>>> print(column("x", String) + "some string")
x || :x_1此运算符将生成适当的特定于数据库的结构,例如在 MySQL 上,它历史上一直是
concat()
SQL 函数>>> print((column("x", String) + "some string").compile(dialect=mysql.dialect()))
concat(x, %s) ColumnOperators.regexp_replace()
:作为
ColumnOperators.regexp()
的补充,它为支持它的后端生成 REGEXP REPLACE 等效项>>> print(column("x").regexp_replace("foo", "bar").compile(dialect=postgresql.dialect()))
REGEXP_REPLACE(x, %(x_1)s, %(x_2)s)-
生成 COLLATE SQL 运算符,该运算符在表达式时提供特定整理
>>> print( ... (column("x").collate("latin1_german2_ci") == "Müller").compile( ... dialect=mysql.dialect() ... ) ... )
(x COLLATE latin1_german2_ci) = %s要对文字值使用 COLLATE,请使用
literal()
结构>>> from sqlalchemy import literal >>> print( ... (literal("Müller").collate("latin1_german2_ci") == column("x")).compile( ... dialect=mysql.dialect() ... ) ... )
(%s COLLATE latin1_german2_ci) = x
算术运算符¶
ColumnOperators.__add__()
,ColumnOperators.__radd__()
(Python “+
” 运算符)>>> print(column("x") + 5)
x + :x_1>>> print(5 + column("x")):x_1 + x请注意,当表达式的 datatype 为
String
或类似类型时,ColumnOperators.__add__()
运算符反而会生成 字符串连接。ColumnOperators.__sub__()
,ColumnOperators.__rsub__()
(Python “-
” 运算符)>>> print(column("x") - 5)
x - :x_1>>> print(5 - column("x")):x_1 - xColumnOperators.__mul__()
,ColumnOperators.__rmul__()
(Python “*
” 运算符)>>> print(column("x") * 5)
x * :x_1>>> print(5 * column("x")):x_1 * xColumnOperators.__truediv__()
,ColumnOperators.__rtruediv__()
(Python “/
” 运算符)。这是 Pythontruediv
运算符,它将确保整数真除法发生>>> print(column("x") / 5)
x / CAST(:x_1 AS NUMERIC)>>> print(5 / column("x")):x_1 / CAST(x AS NUMERIC)在版本 2.0 中变更: Python
/
运算符现在确保整数真除法发生ColumnOperators.__floordiv__()
,ColumnOperators.__rfloordiv__()
(Python “//
” 运算符)。这是 Pythonfloordiv
运算符,它将确保地板除法发生。对于默认后端以及 PostgreSQL 等后端,SQL/
运算符通常对于整数值以这种方式运行>>> print(column("x") // 5)
x / :x_1>>> print(5 // column("x", Integer)):x_1 / x对于默认情况下不使用地板除法的后端,或者与数字值一起使用时,FLOOR() 函数用于确保地板除法
>>> print(column("x") // 5.5)
FLOOR(x / :x_1)>>> print(5 // column("x", Numeric))FLOOR(:x_1 / x)在版本 2.0 中新增: 支持 FLOOR 除法
ColumnOperators.__mod__()
,ColumnOperators.__rmod__()
(Python “%
” 运算符)>>> print(column("x") % 5)
x % :x_1>>> print(5 % column("x")):x_1 % x
按位运算符¶
按位运算符函数提供跨不同后端统一访问按位运算符,这些运算符预计对兼容值(如整数和位字符串(例如 PostgreSQL BIT
等))起作用。请注意,这些**不是**一般的布尔运算符。
在版本 2.0.2 中新增: 添加了用于按位运算的专用运算符。
ColumnOperators.bitwise_not()
,bitwise_not()
。作为列级方法提供,对父对象生成按位 NOT 子句>>> print(column("x").bitwise_not()) ~x
此运算符也可以作为列表达式级方法提供,对单个列表达式应用按位 NOT
>>> from sqlalchemy import bitwise_not >>> print(bitwise_not(column("x"))) ~x
ColumnOperators.bitwise_and()
生成按位 AND>>> print(column("x").bitwise_and(5)) x & :x_1
ColumnOperators.bitwise_or()
生成按位 OR>>> print(column("x").bitwise_or(5)) x | :x_1
ColumnOperators.bitwise_xor()
生成按位 XOR>>> print(column("x").bitwise_xor(5)) x ^ :x_1
对于 PostgreSQL 方言,使用“#”表示按位 XOR;在使用这些后端之一时,它会自动发出
>>> from sqlalchemy.dialects import postgresql >>> print(column("x").bitwise_xor(5).compile(dialect=postgresql.dialect())) x # %(x_1)s
ColumnOperators.bitwise_rshift()
,ColumnOperators.bitwise_lshift()
生成按位移位运算符>>> print(column("x").bitwise_rshift(5)) x >> :x_1 >>> print(column("x").bitwise_lshift(5)) x << :x_1
使用连接和否定¶
最常见的连接“AND”会在我们多次使用 Select.where()
方法时自动应用,以及类似的方法(如 Update.where()
和 Delete.where()
)
>>> print(
... select(address_table.c.email_address)
... .where(user_table.c.name == "squidward")
... .where(address_table.c.user_id == user_table.c.id)
... )
SELECT address.email_address
FROM address, user_account
WHERE user_account.name = :name_1 AND address.user_id = user_account.id
Select.where()
、Update.where()
和 Delete.where()
也接受多个表达式,效果相同。
>>> print(
... select(address_table.c.email_address).where(
... user_table.c.name == "squidward",
... address_table.c.user_id == user_table.c.id,
... )
... )
SELECT address.email_address
FROM address, user_account
WHERE user_account.name = :name_1 AND address.user_id = user_account.id
“AND” 连接词及其对应的 “OR” 连接词都可以直接使用 and_()
和 or_()
函数。
>>> from sqlalchemy import and_, or_
>>> print(
... select(address_table.c.email_address).where(
... and_(
... or_(user_table.c.name == "squidward", user_table.c.name == "sandy"),
... address_table.c.user_id == user_table.c.id,
... )
... )
... )
SELECT address.email_address
FROM address, user_account
WHERE (user_account.name = :name_1 OR user_account.name = :name_2)
AND address.user_id = user_account.id
可以使用 not_()
函数进行否定。这通常会反转布尔表达式中的操作符。
>>> from sqlalchemy import not_
>>> print(not_(column("x") == 5))
x != :x_1
它也可能在适当的时候应用 NOT
这样的关键字。
>>> from sqlalchemy import Boolean
>>> print(not_(column("x", Boolean)))
NOT x
连接操作符¶
上述连接函数 and_()
、or_()
、not_()
也以重载的 Python 操作符的形式提供。
注意
Python 的 &
、|
和 ~
操作符在语言中具有很高的优先级;因此,对于本身包含表达式的操作数,通常必须应用括号,如下面的示例所示。
Operators.__and__()
(Python 的 “&
” 操作符)Python 二元
&
操作符被重载以与and_()
行为相同(请注意两个操作数周围的括号)。>>> print((column("x") == 5) & (column("y") == 10))
x = :x_1 AND y = :y_1Operators.__or__()
(Python 的 “|
” 操作符)Python 二元
|
操作符被重载以与or_()
行为相同(请注意两个操作数周围的括号)。>>> print((column("x") == 5) | (column("y") == 10))
x = :x_1 OR y = :y_1Operators.__invert__()
(Python 的 “~
” 操作符)Python 二元
~
操作符被重载以与not_()
行为相同,要么反转现有的操作符,要么将NOT
关键字应用于整个表达式。>>> print(~(column("x") == 5))
x != :x_1>>> from sqlalchemy import Boolean >>> print(~column("x", Boolean))NOT x
flambé! 龙和 炼金术士 图像设计由 Rotem Yaari 创建并慷慨捐赠。
使用 Sphinx 7.2.6 创建。文档最后生成时间:2024 年 11 月 8 日星期五 上午 08:41:19 EST