Loading...
墨滴

小摩托

2021/12/05  阅读:37  主题:橙心

Ftrack Api 入门教程02

Query查询

api 查询对象有两个方法 session.queryseesion.get,这里我们就先聊一下通过 query 方法来获取对象。

query 查询的语法和 SQL 语句很类似

select 要获取的字段 from 要查询的类型 where 要查询的判断条件

其中,要查询的字段和要查询的条件都是可以省略的。所以,最简单的查询条件可以写做

session.query('Shot')

获取结果

query 方法返回的对象并不是查询的结果,而是一个 ftrack_api.query.QueryResult 对象,这个对象里面其实只存储了我们的查询语句,并没有存储我们的查询结果。

只有我们在调用 QueryResultall / one / first 方法的时候才会返回结果。

session.query('Shot').all()

这种链式调用和一些 orm 框架很像,比如 Django 用的 SQLAalchemy,都是在调用 all / one / first 方法的时候才会去请求服务器。

all: 返回所有查询到的结果

first: 返回一条结果,如果没有则返回 None

one: 有且只有一条结果的时候才返回一条结果,如果没有则抛出 ftrack_api.exception.NoResultFoundError 异常,如果查询到多条数据则抛出 ftrack_api.exception.MultipleResultsFoundError 异常。

查询条件

查询条件的格式如下

查询的字段 操作符 查询的字段的期望值

支持的操作符

Operators Example
= is name is “martin”
!= is_not name is_not “martin”
> after greater_than start after “2015-06-01”
< before less_than end before “2015-06-01”
>= bid >= 10
<= bid <= 10
in status.type.name in (“In Progress”, “Done”)
not_in status.name not_in (“Omitted”, “On Hold”)
like name like “%thrones”
not_like name not_like “%thrones”
has author has (first_name is “Jane” and last_name is “Doe”)
any metadata any (key=some_key and value=some_value)

一些小例子

is

# 获取所有项目状态为active的项目对象
session.query(
    'Project where status is active'
).all()

like

session.query(
    'Project where status is active and '
    '(name like "%thrones" or full_name like "%thrones")'
).all()

in

# 要注意的是如果期望值中间有空格或者有其他特殊符号(比如:In Progress),那么一定要用双引号将其包裹起来
session.query(
    'Task where status.name in ("In Progress", "Done")'
).all()

has

notes_written_by_jane_doe = session.query(
    'Note where author has (first_name is "Jane" and last_name is "Doe")'
).all()

上面的语句用 is 操作符可以写成这样

notes_written_by_jane_doe = session.query(
    'Note where author.first_name is "Jane" and author.last_name is "Doe"'
).all()

但是理论上,has 的性能要比 is 的高

any

这个对于要查询的字段是字典类型(ftrack_api.collection.KeyValueMappedCollectionProxy)的对象尤为好用

比如,要查询查询出所有自定义属性eps字段为e03的所有镜头

session.query(
    'Shot where custom_attributes any (key=eps and value=e03)'
).all()

还有一个比较好用的查询字段是 object_type , 这个字段可以直接在查询的时候过滤出来对象的类型

比如,要查询父级是 Shot 类型的 Task 对象

session.query(
 'Task where parent.object_type is Shot'
)

使用projections优化

当我们在没有设置要获取的字段的时候,我们在请求的时候会自动填充一个默认的字段

比如当我们写成Project where status is active 的时候,api 会在请求前 填充一个 id,请求语句就变成了select id from Project where status is active.

如果想查看对应的类型具体填充了哪些字段,可以打印一下 session.types['类型名'].default_projections,可以看到对应的默认填充的字段。

没有被填充的字段,返回的数据将会用ftrack_api.symbol.Symbol(NOT_SET)填充。

那么就会出现这种情况,我们通过下面的语句获取的了一个 shot 对象

shot = session.query('Shot').first()

由于默认字段大部分都是 id,所以返回的对象,其实只有 id 字段是真正有数据的。

当我们再去请求其他字段的时候,比如获取 shot['name'] 值的时候,api会再向服务器发送一次请求(select name from Shot where id is shot['id'])。

如果在我们的代码下面又去获取了 shot['parent']['name'] 值的时候,api会再向服务器发送一次请求(select parent.name from Shot where id is shot['id'])。

这样就会导致增加本地向服务器请求的次数,给服务器造成了大量的查询负担。

所以,官方非常建议大家最好在过滤查询的时候,就将后面要用的字段通过 select 来获取出来,这样在后面使用的时候,就不会再向服务器去请求了,而是直接使用对象里面的缓存数据。

shot = session.query(
    'select id,name,parent.name from Shot'
).first()

从而减小了服务器的查询负担以及本地代码的执行效率。

特别注意的是,尽量只去获取后面代码用到的字段,获取过多的字段或者过深的字段(比如 parent.parent.parent.parent.parent.status.name)也会影响代码执行效率。

小摩托

2021/12/05  阅读:37  主题:橙心

作者介绍

小摩托