FTRACKクエリは、FTRACK API上のオブジェクト指向のラッパーです。デフォルトのクエリ構文は強力ですが、完全にテキストベースであるため、動的クエリを構築するのが難しい場合があります。このモジュールは、ネストされた比較でサポートおよび/または演算子をサポートします。
ftrack APIの仕組みを基本的に理解するために、最初にhttps://ftrack-python-api.readthedocs.io/en/stable/tutorial.htmlを読むことをお勧めします。
pip install ftrack_query
クエリ文字列全体を一度に記述する代わりに、「ステートメント」が作成され(例: stmt = select('Task') )、クエリは、ステートメントの.where()や.populate()などのメソッドを呼び出すことで構築できます。
CRUDメソッドはすべてサポートされています( create 、 select 、 update 、 delete )が、主な機能はselectで使用するために設計されています。ステートメントは、メインAPIと同様の構文で構築されるため、2つの間の移行を簡単にする必要があります。
これは完全に後方互換性があるため、既存のクエリを書き直す必要はないことに注意してください。
以下の例は、非常に基本的なクエリ用です。
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 () attr() 、 and_() 、およびor_()は、 ftrack_queryとftrack_query.eventの両方に存在することに注意してください。これらは交換可能ではないため、両方が必要な場合は、 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 (...) Calling session.execute(stmt) .one() .first()を実行し、Ftrack独自のQueryResultオブジェクト.all()返します。または、ショートカットsession.select(entity)を使用すると、これがスキップされる場合があります。
結果をフィルタリングします。
キーワードを使用することは.where(first_name='Peter', last_name='Hunt')など、最速の方法です。 equalityチェックよりも複雑なものについては、 attr() .where(attr('project.metadata').any(attr('key') != 'disabled'))
プレフェッチエンティティの属性。
例として、すべてのユーザーの名前を反復するために、クエリの一部として.populate('first_name', 'last_name')を呼び出すことをお勧めします。それがなければ、ユーザーごとに2つの個別のクエリが必要です。これは、n+1クエリの問題として知られています。
属性で結果を並べ替えます。
属性と順序は、format attr('name').desc()で、またはname descendingなどの生文字列として与えることができます。注文は、提供されていない場合、デフォルトでascendingことになります。
ソート方向を逆にします。
結果の量を特定の値に制限します。
注:これは.first()または.one()を呼び出すことと互換性がありません。
制限を使用する場合、返される結果にオフセットを適用します。
上級ユーザーのみ。
page_size :FTRACKから一度にフェッチする結果の数を設定します。session :セッションオブジェクトをクエリに添付します。声明を.in_()内で使用するサブクエリにします。
これにより、ステートメントの一部として「Select From」が常にあることが保証されます。属性パラメーターを手動で設定すると、既存の投影がオーバーライドされます。
新しいエンティティの作成に使用されます。
from ftrack_query import create
stmt = create ( entity ). values (...) Calling 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 ) Calling session.execute(stmt)は、削除されたエンティティの数を返します。
更新するものをフィルタリングします。
remove_components :削除される前に、コンポーネントエンティティを含むすべてのLocationからComponentエンティティを削除します。これは、ロールバックできないため、デフォルトでは有効になりません。 Comparisonオブジェクトは、データを文字列に変換するように設計されています。他のComparisonオブジェクトを含む、任意のデータ型に対して使用できる幅広いオペレーターが含まれています。 function 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_('select id from table where x is y') 、または.in_(['x', 'y'])などのアイテムのリスト)を受け入れることができます。
文字列がクエリ内に含まれているかどうかを確認します。 likeまたはnot_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 ))