Запрос FTRACK-это объектно-ориентированная обертка над API FTRACK. Хотя синтаксис запроса по умолчанию является мощным, он полностью основан на текстовых условиях, поэтому динамические запросы могут быть трудно построить. Этот модуль поддерживает и / или операторы с вложенными сравнениями.
Рекомендуется сначала прочитать https://ftrack-python-api.readthedocs.io/en/stable/tutorial.html для базового понимания того, как работает API ftrack.
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 () Обратите внимание, что 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) выполнит собственный объект QueryResult FTRACK, из которого могут быть вызваны .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_() .
Это гарантирует, что всегда есть «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 (...) Calling session.execute(stmt) вернет, сколько объектов было найдено и обновлялось.
Фильтруйте, что обновить.
Значения для обновления объекта.
Используется для удаления сущностей. Это построено из метода select поэтому содержит много тех же методов.
from ftrack_query import delete
stmt = delete ( entity ). where (...). options ( remove_components = True ) Calling session.execute(stmt) вернет, сколько организаций было удалено.
Фильтруйте, что обновить.
remove_components : удалите любую Component сущность из всех Location содержащих его до того, как он будет удален. Это не включено по умолчанию, так как его нельзя откатить назад. Объект 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')
Проверьте, находится ли строка в запросе. Используйте процентный знак в качестве подстановочного знака, если 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 ))