操作员参考
本节详细介绍可用于构造SQL表达式的运算符的用法。
这些方法是根据 Operators
和 ColumnOperators
基类。这些类的后代可以使用这些方法,包括:
Column
物体ColumnElement
对象,它们是所有核心SQL表达式语言列级表达式的根InstrumentedAttribute
对象是映射的属性。
在教程部分中首先介绍了运算符,包括:
SQLAlchemy 1.4/2.0教程 - unified tutorial in 2.0 style
对象关系教程(1.x API) - ORM tutorial in 1.x style
SQL表达式语言教程(1.x API) - Core tutorial in 1.x style
比较运算符
适用于许多数据类型(包括数字、字符串、日期等)的基本比较:
ColumnOperators.__eq__()
(Python“==
”运算符)::>>> print(column('x') == 5) x = :x_1
ColumnOperators.__ne__()
( Python “`”!=``“运算符)::>>> print(column('x') != 5) x != :x_1
ColumnOperators.__gt__()
(Python“>”运算符)::>>> print(column('x') > 5) x > :x_1
ColumnOperators.__lt__()
(Python“<”运算符)::>>> print(column('x') < 5) x < :x_1
ColumnOperators.__ge__()
(Python“>=`”运算符)::>>> print(column('x') >= 5) x >= :x_1
ColumnOperators.__le__()
(Python“<=`”运算符)::>>> print(column('x') <= 5) x <= :x_1
>>> print(column('x').between(5, 10)) x BETWEEN :x_1 AND :x_2
在比较中
sqlin操作符在SQLAlchemy中是一个独立的主题。由于IN运算符通常用于固定值列表,SQLAlchemy的绑定参数强制特性使用了一种特殊的SQL编译形式,该编译将呈现一个临时SQL字符串,以便在第二步中形成绑定参数的最终列表。换言之,“它就是有效的”。
在值列表中
通常,通过将值列表传递给 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)
表达式中为空
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运算符呈现。
不在
“不在”可通过 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]))
表达式中的元组
元组与元组的比较在中很常见,因为在将行与一组潜在的复合主键值进行匹配时,其他用例都适用于这种情况。这个 tuple_()
construct为元组比较提供了基本的构建块。这个 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',)]
子查询输入
最后, 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()
结构:>>> from sqlalchemy import null >>> print(column('x').is_(null())) x IS NULL
这个
ColumnOperators.is_()
使用运算符时自动调用ColumnOperators.__eq__()
重载运算符,即。==
,与None
或null()
价值观。这样,通常不需要使用ColumnOperators.is_()
显式地,当与动态值一起使用时:>>> a = None >>> print(column('x') == a) x IS NULL
注意 Python
is
操作员是 不超载 . 即使Python为重载操作符提供了钩子,比如==
和!=
是的 not 提供任何重新定义的方法is
.类似
ColumnOperators.is_()
,产生“不是”:>>> print(column('x').is_not(None)) x IS NOT NULL
类似于
!= None
::>>> print(column('x') != None) x IS NOT NULL
ColumnOperators.is_distinct_from()
:生成的SQL不同于:
>>> print(column('x').is_distinct_from('some value')) x IS DISTINCT FROM :x_1
ColumnOperators.isnot_distinct_from()
:生成的SQL与以下对象不同:
>>> 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()
:
ColumnOperators.startswith()
::The string containment operators >>> 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 || '%'
字符串匹配
匹配运算符始终特定于后端,并且可能在不同的数据库上提供不同的行为和结果:
这是一个特定于方言的运算符,它使用底层数据库的匹配功能(如果可用):
>>> 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__()
,也就是 Python+
运算符,当使用派生自String
::>>> 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
注意,当表达式的数据类型为
String
或者类似的ColumnOperators.__add__()
操作员却生成 string concatenation .ColumnOperators.__sub__()
,ColumnOperators.__rsub__()
(Python“-”运算符)::>>> print(column('x') - 5) x - :x_1 >>> print(5 - column('x')) :x_1 - x
ColumnOperators.__mul__()
,ColumnOperators.__rmul__()
(Python“*`”运算符)::>>> print(column('x') * 5) x * :x_1 >>> print(5 * column('x')) :x_1 * x
ColumnOperators.__div__()
,ColumnOperators.__rdiv__()
(Python“/”运算符)::>>> print(column('x') / 5) x / :x_1 >>> print(5 / column('x')) :x_1 / x
ColumnOperators.__mod__()
,ColumnOperators.__rmod__()
(Python“%`”运算符)::>>> print(column('x') % 5) x % :x_1 >>> print(5 % column('x')) :x_1 % x
使用连词和否定词
如果我们重复使用 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_1
Operators.__or__()
(Python“|`
”运算符):Python二进制文件
|
运算符的行为与or_()
(注意两个操作数周围的括号)::>>> print((column('x') == 5) | (column('y') == 10)) x = :x_1 OR y = :y_1
Operators.__invert__()
(Python“~”运算符):Python二进制文件
~
运算符的行为与not_()
,或者反转现有运算符,或者应用NOT
整个表达式的关键字::>>> print(~(column('x') == 5)) x != :x_1 >>> from sqlalchemy import Boolean >>> print(~column('x', Boolean)) NOT x
操作员自定义
TODO