前言:

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

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

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

正文:

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

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

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

注意:给定字段需要满足在图式中 filter 属性的 enabled 不为 false,如果为 false 则排序无效,目前 summary、lambda 及 pivot 字段不支持排序。

一、下面我们从 filters 语句的一般形式开始,以下是一个最基本的查询子句:

[字段, 比较运算符,]

让我们看一个更具体的示例,构造一条查询语句,把它作为 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 参数。

filters 参数的构造语句至少包含一个 查询子句,其中一定包含一个 比较运算符

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"}])

contains、excludes、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。