前言:
要使用 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"
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。