本节详细介绍可用于构造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_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_2sqlin操作符在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 NULLColumnOperators.is_distinct_from() :
生成的SQL不同于:
>>> print(column('x').is_distinct_from('some value'))
x IS DISTINCT FROM :x_1ColumnOperators.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_1ColumnOperators.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) = xColumnOperators.__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 - xColumnOperators.__mul__() , ColumnOperators.__rmul__() (Python“*`”运算符)::
>>> print(column('x') * 5)
x * :x_1
>>> print(5 * column('x'))
:x_1 * xColumnOperators.__div__() , ColumnOperators.__rdiv__() (Python“/”运算符)::
>>> print(column('x') / 5)
x / :x_1
>>> print(5 / column('x'))
:x_1 / xColumnOperators.__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.idSelect.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 xTODO
flambé! the dragon and The Alchemist image designs created and generously donated by Rotem Yaari.
Created using Sphinx 4.2.0.