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 ))