前言:

要使用 Orchestra Python API (下文简称 api) 查询数据,就需要使用 read 方法。

read 方法提供丰富的过滤、聚合、排序选项,在用户权限范围内支持查询一切实体类型,且线程安全,可放心使用。

本节详细说明 read 方法的 filters 参数,它既是 api 的灵魂,又是学习过程中的一大难点。

正文:

filters 参数又名 过滤条件,用于传入 filters 语句,过滤出满足条件的数据。

filters 语句与后端接口同构,确保 api 与前端的查询结果一致。

filters 语句覆盖绝大部分查询需求,即使是复杂的跨表查询依然能保证较高的性能。

注意:如果给定字段在图式中的  filter 对象的  enabled 属性为  false,则该字段不支持排序。此外 summary、lambda 、 pivot 字段也不支持排序。

一、下面我们从过滤条件的一般形式开始,最基础的过滤条件由 字段、比较运算符、值 组成:

[字段, 比较运算符, 值]

这里构造一个过滤条件,把它作为 filters 参数时会查询所有 name 属性等于 Layout 的数据:

["name", "is", "Layout"]

让我们再写一条更完整的 read 语句,下面的例句会查询所有 name 属性等于 Layout 的 Task 数据。

api.read("Task", filters=["name", "is", "Layout"])

上面这条 read 语句可以很直观地翻译成 sql 伪代码,有 sql 经验的开发者可以很轻易地抓住其中的要点:

select * from Task where name = 'Layout';

二、在实际应用中,我们的过滤条件往往会更为复杂,不仅会包含比较运算符,还会包含逻辑运算符。

我们通常使用逻辑运算符连接两条或者更多的过滤子条件,其一般形式为:

[逻辑运算符, [字段, 比较运算符, 值], [字段, 比较运算符, 值]]

它可以扩展为更复杂的形式。

下面的 read 语句的 filters 参数就包含了一个名为 or 的逻辑运算符,表示逻辑和,即“或者”的关系:

api.read("Task", filters=["or", ["name", "is", "Layout"], ["name", "is", "Animation"]])

这条 read 语句表示:查询 name 属性等于 Layout 或者 name 属性等于 Animation 的 Task 数据。

如果要表示逻辑积,即“并且”的关系,则需要使用名为 and 的逻辑运算符,语句如下:

api.read("Task", filters=["and", ["name", "is", "Layout"], ["name", "is", "Animation"]])

这条 read 语句表示:在 Task 表中查询 name 属性等于 Layout 并且 name 属性等于 Animation 的数据。

name 字段的值既要等于 Layout 又要等于 Animation,这条 read 语句的执行结果想必一定为空。

实际上 and 逻辑运算符是可以省略的,我们经常看到下面的 read 语句,其中的 filters 语句包含了三个过滤子条件,默认使用了 and 逻辑运算符:

api.read("Task", filters=[["name", "is", "Layout"], ["name", "is", "Animation"], ["name", "is", "Model"]])

三、有了以上知识,下面让我们更全面地认识 filters 参数。

简单的过滤条件至少包含一个 比较运算符。

复杂的过滤条件至少包含一个 逻辑运算符,由它连接一个以上的 过滤子句。

1.  Orchestra Python API 提供了丰富的比较运算符,它们分别是:

"is", "is_not", "less_than", "greater_than", "contains", "excludes", "in", "not_in", "starts_with", "ends_with"

比较运算符的详细说明可以参考:自定义页面过滤条件

开发者可以使用它们构造条件更复杂的过滤子条件,需要注意的是,less_than、greater_than 要求子句中值为数字类型,in、not_in 要求子句中值为列表类型。比如:

api.read("Task", filters=["id", "less_than", 100]) 
api.read("Task", filters=["name", "in", ["Animation", "Layout"]])

而 is、is_not 运算符则要求值与字段类型一致,比如 project 字段是单一实体类型,则值应该是实体类型,即包含 id 与 type 的字典,比如:

api.read("Task", filters=["project", "is", {"id": 1, "type": "Project"}])

starts_with、ends_with 要求值为字符串类型,比如:

api.read("Task", filters=["name", "starts_with", "Lay"])

2. Orchestra Python API 提供了两个逻辑运算符,它们分别是 or 和 and,在上面示例中我们已经有所了解,实际上利用逻辑运算符,我们可以构造更为复杂的 filters 语句:

api.read("Task", filters=["or", [["project", "is", {"id": 1, "type": "Project"}], ["name", "is", "Animation"]], ["name", "is", "Layout"]])

这条语句表示查找 project 属性等于 {“id”: 1, “type”: “Project”} 且 name 属性等于 Animation 的 Task 数据或者查找 name 属性等于 Layout 的 Task 数据。

3. Orchestra Python API 在过滤条件中支持使用路由路径型字段。

路由路径型字段一般表示为:

project.Project.id 
entity.Shot.id 
attachment_links.Reply.entity.Note.id 
event_log_entry.EventLogEntry.entity.Note.user.HumanUser.name
使用路由路径型字段我们可以轻松地实现跨表查询,比如:

api.read("Task", filters=["entity.Shot.code", "contains", "001"])

这条 read 语句表示查询满足以下条件的 Task 数据,即 entity 属性必须为 Shot 实体类型,且 Shot 实体的 code 属性必须包含 001。