Expression API
Expression API允许用户动态构建表达式,这些表达式通常就是配合Relational API中的各种操作来构造 SELECT 语句。Expression API 提供了五种表达式抽象:
ColumnExpression(column:str)
: 按照名称引用列,说白了就是对列名进行包装为 Expression 对象StarExpression(exclude:list)
: 所有列,可以使用 exclude 来指定需要排除的列,在大多数时候等价于*[ColumnExpression(column_1) ....]
ConstantExpression(value)
: 常量表达式,说白了就是将常量包装为 Expression 对象CaseExpression(condition: Expression, then_value: ConstantExpression)
: 分支表达式,SQL 里面的 IF ELSE 语句FunctionExpression(func_name:str, *args: Expression)
: 构造函数表达式,func_name 必须是 SQL 函数或者 UDF 函数
以上五个表达式对象还绑定了一些通用的操作:
alias(name:str)
: 别名,对应的 AS 操作cast(type: DuckDBPyType)
: 类型转换,对应的 CAST 或者::text
这样的操作isin(*expres: Expression)
: IN 表达式,其中可以是结果为列表的其他表达式isnotin(*expres: Expression)
: NOT IN 表达式,其中可以是结果为列表的其他表达式isnotnull()
: 检测表达式是否不是 NULLisnull()
: 检测表达式是否是 NULL
如果表达式提供给 DuckDBPyRelation.order()
时,可以执行以下操作:
asc()
: 指示表达式升序排序desc()
: 指示表达式降序排列nulls_first()
: 指示表达式中的 null 值位于非 null 值之前nulls_last()
: 指示表达式中的 null 值位于非 null 值之后
ColumnExpression 和 StarExpression
这两个都是用于选择列的表达式,说白了他就是 SQL 中列的双引号:
Python
import duckdb
import pandas as pd
df = pd.DataFrame(
{"a": [1, 2, 3, 4], "b": [True, None, False, True], "c": [42, 21, 13, 14]}
)
# selecting a single column
col = duckdb.ColumnExpression("a")
res = duckdb.from_df(df).select(col).fetchall()
print(res)
# selecting multiple columns
col_list = [
duckdb.ColumnExpression("a") * 10,
duckdb.ColumnExpression("b").isnull(),
duckdb.ColumnExpression("c") + 5,
]
res = duckdb.from_df(df).select(*col_list).fetchall()
print(res)
# StarExpression 能够选择所有的,可以通过 exclude 来排除指定列
star = duckdb.StarExpression(exclude=["b"])
res = duckdb.df(df).select(star).fetchall()
print(res)
[(1,), (2,), (3,), (4,)]
[(10, False, 47), (20, True, 26), (30, False, 18), (40, False, 19)]
[(1, 42), (2, 21), (3, 13), (4, 14)]
SQL 中任何需要列名(标准需要双引号)的地方都需要使用列表达式封装。如果需要对列进行详细的处理就使用 ColumnExpression,如果只是想处理多列就使用 StarExpression 他比较方便。
ConstantExpression
常量表达式,说白了就是 SQL 中对常量的单引号:
Python
import duckdb
import pandas as pd
df = pd.DataFrame(
{"a": [1, 2, 3, 4], "b": [True, None, False, True], "c": [42, 21, 13, 14]}
)
const = duckdb.ConstantExpression("hello")
res = duckdb.df(df).select(const).fetchall()
print(res)
[('hello',), ('hello',), ('hello',), ('hello',)]
SQL 中任何需要常量的地方都需要使用常量表达式封装。
CaseExpression
分支表达式,他等价于 SQL 语句中的:
当然 ELSE 需要配合 otherwise(value)
函数来使用,对于 CaseExpression 则只针对于 condition 和 WHEN 中的 value:
Python
import duckdb
import pandas as pd
from duckdb import ConstantExpression, ColumnExpression, CaseExpression
df = pd.DataFrame(
{"a": [1, 2, 3, 4], "b": [True, None, False, True], "c": [42, 21, 13, 14]}
)
hello = ConstantExpression("hello")
world = ConstantExpression("world")
case = CaseExpression(condition=ColumnExpression("b") == False, value=world).otherwise(
hello
)
res = duckdb.df(df).select(case).fetchall()
print(res)
[('hello',), ('hello',), ('world',), ('hello',)]
FunctionExpression
包含函数调用,他可以通过提供函数名称和任意数量的表达式作为参数来构造表达式:
Python
import duckdb
import pandas as pd
from duckdb import ConstantExpression, ColumnExpression, FunctionExpression
df = pd.DataFrame(
{
"a": [
"test",
"pest",
"text",
"rest",
]
}
)
ends_with = FunctionExpression(
"ends_with", ColumnExpression("a"), ConstantExpression("est")
)
res = duckdb.df(df).select(ends_with).fetchall()
print(res)
[(True,), (True,), (False,), (True,)]
这其中的函数名必须是 SQL 的内置函数以及用户自定义的过程函数(UDF)。