Ftrack查询是Ftrack API上的面向对象的包装器。尽管默认查询语法功能强大,但它完全基于文本,因此动态查询可能很难构造。该模块通过嵌套比较支持和/或操作员。
建议先阅读https://ftrack-python-api.readthedocs.io/en/stable/tutorial.html,以对FTRACK API的工作方式有基本的了解。
pip install ftrack_query
与其立刻编写整个查询字符串,不如构造一个“语句”(例如stmt = select('Task') ),可以通过调用语句上.where()和.populate()等方法来构建查询。
CRUD方法都得到支持( create , select , update , delete ),但主要功能旨在与select一起使用。语句的构建具有与主API相似的语法,因此在两者之间过渡应该很简单。
请注意,这完全是向后兼容的,因此现有查询无需重写。
以下示例是非常基本的查询:
from ftrack_query import FTrackQuery , attr , create , select , and_ , or_
with FTrackQuery () as session :
# Select
project = session . select ( 'Project' ). where ( name = 'Test Project' ). one ()
# Create
task = session . execute (
create ( 'Task' ). values (
name = 'My Task' ,
project = project ,
)
)
session . commit ()
# Update
rows_updated = session . execute (
update ( 'Task' )
. where ( name = 'Old Task Name' )
. values ( name = 'New Task Name' )
)
session . commit ()
# Delete
rows_deleted = session . execute (
delete ( 'Task' ). where (
name = 'Old Task Name' ,
)
)
session . commit ()对于一个更复杂的例子:
ATTR_TYPE = attr ( 'type.name' )
TASK_STMT = (
select ( 'Task' )
# Filter the tasks
. where (
# Get any task without these statuses
~ attr ( 'status.name' ). in_ ([ 'Lighting' , 'Rendering' ]),
# Check for notes matching any of the following conditions:
attr ( 'notes' ). any (
# Ensure note was posted by someone outside the company
~ attr ( 'user.email' ). endswith ( '@company.com' )
# Ensure note either not completable or not completed
or_ (
and_ (
completed_by = None ,
is_todo = True ,
),
is_todo = False ,
),
),
# Ensure it has an animation task
or_ (
ATTR_TYPE . contains ( 'Animation' ),
ATTR_TYPE == 'Anim_Fixes' ,
),
),
# Order the results
. order_by (
ATTR_TYPE . desc (), # Equivalent to "type.name desc"
'name' ,
)
# Use projections to populate attributes as part of the query
. populate (
'name' ,
'notes' ,
'status.name' ,
ATTR_TYPE ,
)
. limit ( 5 )
)
with FTrackQuery () as session :
# Filter the above query to the result of another query
task_stmt = TASK_STMT . where (
project_id = session . select ( 'Project' ). where ( name = 'Test Project' ). one ()[ 'id' ]
)
# Use the current session to execute the statement
tasks = session . execute ( task_stmt ). all ()事件系统使用略有不同的查询语言。
from ftrack_query import FTrackQuery , event
from ftrack_query . event import attr , and_ , or_
with FTrackQuery () as session :
session . event_hub . subscribe ( str (
and_ (
attr ( 'topic' ) == 'ftrack.update' ,
attr ( 'data.user.name' ) != getuser (),
)
))
session . event_hub . wait ()请注意, ftrack_query和ftrack_query.event中都存在attr() , and_()和or_() 。这些不是可互换的,因此,如果两者都需要,请导入event并将其用作名称空间。
从ftrack_api.Session继承的主会话。
加入多个比较。
& |提供快捷方式(例如, attr(a).contains(b) & attr(x).contains(y) )。
反转输入比较。
提供~ (例如~attr(x).contains(y) )的快捷方式。
用于构建查询字符串。
from ftrack_query import select
stmt = select ( entity ). where (...). populate (...)呼叫session.execute(stmt)将执行查询并返回ftrack自己的QueryResult对象,从中可以调用.one() ,. .first()或.all() 。或者,通过使用快捷键session.select(entity) ,可以跳过。
过滤结果。
使用关键字是最快的方法,例如.where(first_name='Peter', last_name='Hunt') 。对于比平等检查更复杂的任何内容,建议使用attr() ,例如.where(attr('project.metadata').any(attr('key') != 'disabled')) 。
预提取实体属性。
一个示例,为了通过每个用户的名称迭代,可以作为查询的一部分打电话.populate('first_name', 'last_name')是一个好主意。没有这些,每个用户将需要2个单独的查询,这称为n+1查询问题。
通过属性对结果进行排序。
属性和顺序可以以格式attr('name').desc()或作为原始字符串(例如name descending给出。订单将默认为ascending如果不提供)。
反向分类方向。
将结果量限制为一定值。
注意:这与调用.first()或.one()不兼容。
在使用限制的情况下,将偏移偏移到返回的结果中。
仅适用于高级用户。
page_size :设置要立即从ftrack获取的结果数。session :将会话对象附加到查询。使该语句作为.in_()中的子查询。
这样可以确保始终有一个“选择”作为陈述的一部分。手动设置属性参数将覆盖任何现有的预测。
用于创建新实体。
from ftrack_query import create
stmt = create ( entity ). values (...)呼叫session.execute(stmt)将返回创建的实体。
用来创建实体的值。
用于在多个实体上批量更新值。这是由select方法构建的,因此包含许多相同的方法。
from ftrack_query import update
stmt = update ( entity ). where (...). values (...)呼叫session.execute(stmt)将返回找到和更新多少个实体。
过滤什么要更新。
更新实体的值。
用于删除实体。这是由select方法构建的,因此包含许多相同的方法。
from ftrack_query import delete
stmt = delete ( entity ). where (...). options ( remove_components = True )致电session.execute(stmt)将返回删除多少个实体。
过滤什么要更新。
remove_components :从包含其删除之前的每个Location删除任何Component实体。默认情况下不启用此功能,因为它无法回滚。 Comparison对象旨在将数据转换为字符串。它包含广泛的运算符,可用于任何数据类型,包括其他Comparison对象。函数attr是对此的快捷方式。
任何比较都可以用~前缀或not_函数逆转。
attr(key) == 'value'attr(key) > 5attr(key).like('value%')attr(key).after(arrow.now().floor('day'))attr(key).has(subkey='value')attr(key).any(subkey='value')attr(key).in_(subquery)简单的比较。
执行检查以检查属性是否匹配任何结果。
这可以.in_(['x', 'y'])一个子查询.in_('select id from table where x is y')
检查查询中是否包含一个字符串。如果使用或not_like like则使用百分比作为通配符;其余的是快捷方式,并自动执行此操作。
测试标量和收集关系。
测试日期。建议使用arrow对象。
# Project
select ( 'Project' )
# Project where status is active
select ( 'Project' ). where ( status = 'active' )
# Project where status is active and name like "%thrones"
select ( 'Project' ). where ( attr ( 'name' ). like ( '%thrones' ), status = 'active' )
# session.query('Project where status is active and (name like "%thrones" or full_name like "%thrones")')
select ( 'Project' ). where ( or_ ( attr ( 'name' ). like ( '%thrones' ), attr ( 'full_name' ). like ( '%thrones' )), status = 'active' )
# session.query('Task where project.id is "{0}"'.format(project['id']))
select ( 'Task' ). where ( project = project )
# session.query('Task where project.id is "{0}" and status.type.name is "Done"'.format(project['id']))
select ( 'Task' ). where ( attr ( 'status.type.name' ) == 'Done' , project = project )
# session.query('Task where timelogs.start >= "{0}"'.format(arrow.now().floor('day')))
select ( 'Task' ). where ( attr ( 'timelogs.start' ) >= arrow . now (). floor ( 'day' ))
# session.query('Note where author has (first_name is "Jane" and last_name is "Doe")')
select ( 'Note' ). where ( attr ( 'author' ). has ( first_name = 'Jane' , last_name = 'Doe' ))
# session.query('User where not timelogs any ()')
select ( 'User' ). where ( ~ attr ( 'timelogs' ). any ())
# projects = session.query('select full_name, status.name from Project')
select ( 'Project' ). populate ( 'full_name' , 'status.name' )
# select name from Project where allocations.resource[Group].memberships any (user.username is "john_doe")
select ( 'Project' ). select ( 'name' ). where ( attr ( 'allocations.resource[Group].memberships' ). any ( attr ( 'user.username' ) == 'john_doe' ))
# Note where parent_id is "{version_id}" or parent_id in (select id from ReviewSessionObject where version_id is "{version_id}")
select ( 'Note' ). where ( or_ ( attr ( 'parent_id' ). in_ ( select ( 'ReviewSessionObject' ). where ( version_id = version_id ). subquery ()), parent_id = version_id ))