Ftrack Query est un wrapper orienté objet sur l'API Ftrack. Bien que la syntaxe de requête par défaut soit puissante, elle est entièrement basée sur le texte, de sorte que les requêtes dynamiques peuvent être difficiles à construire. Ce module prend en charge et / ou opérateurs avec des comparaisons imbriquées.
Il est recommandé de lire d'abord https://ftrack-python-api.readthedocs.io/en/stable/tutorial.html pour une compréhension de base du fonctionnement de l'API Ftrack.
pip install ftrack_query
Au lieu d'écrire la chaîne de requête entière à la fois, une "déclaration" est construite ( par exemple stmt = select('Task') ), et la requête peut être construite en appelant des méthodes telles que .where() et .populate() sur l'instruction.
Les méthodes CRUD sont toutes prises en charge ( create , select , update , delete ), mais la fonctionnalité principale est conçue pour être utilisée avec select . Les instructions sont construites avec une syntaxe similaire à l'API principale, il doit donc être simple de passer entre les deux.
Notez que cela est entièrement compatible, de sorte que les requêtes existantes n'ont pas besoin d'être réécrites.
L'exemple ci-dessous est pour les requêtes très basiques:
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 ()Pour un exemple beaucoup plus complexe:
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 ()Le système d'événements utilise un langage de requête légèrement différent.
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 () Notez que attr() , and_() et or_() sont présents dans ftrack_query et ftrack_query.event . Ceux-ci ne sont pas interchangables, donc si les deux sont nécessaires, importez event et utilisez-le comme espace de noms.
Session principale héritée de ftrack_api.Session .
Rejoignez des comparaisons multiples.
Les raccourcis sont fournis avec & et | ( par exemple, attr(a).contains(b) & attr(x).contains(y) ).
Inverser les comparaisons d'entrée.
Un raccourci est fourni avec ~ ( par exemple ~attr(x).contains(y) ).
Utilisé pour construire la chaîne de requête.
from ftrack_query import select
stmt = select ( entity ). where (...). populate (...) L'appel session.execute(stmt) exécutera la requête et renvoie le propre objet QueryResult de Ftrack, à partir de laquelle .one() , .first() ou .all() peut être appelé. Alternativement, en utilisant la session.select(entity) , cela peut être ignoré.
Filtrez le résultat.
L'utilisation de mots clés est le moyen le plus rapide, comme .where(first_name='Peter', last_name='Hunt') . Pour tout ce qui est plus complexe que les vérifications d'égalité, l'utilisation attr() est recommandée, comme .where(attr('project.metadata').any(attr('key') != 'disabled')) .
Attributs d'entité pré-fetch.
Un exemple, afin de parcourir le nom de chaque utilisateur, ce serait une bonne idée d'appeler .populate('first_name', 'last_name') dans le cadre de la requête. Sans cela, il faudrait 2 requêtes distinctes par utilisateur, connues sous le nom de problème de requête N + 1.
Trier les résultats par un attribut.
L'attribut et l'ordre peuvent être donnés dans le format attr('name').desc() , ou en tant que chaîne brute telle que name descending . La commande sera par défaut pour ascending si elle n'est pas fournie.
Inverser la direction de tri.
Limitez la quantité de résultats à une certaine valeur.
Remarque: Ceci est incompatible avec l'appel .first() ou .one() .
Dans le cas de l'utilisation d'une limite, appliquez un décalage au résultat renvoyé.
Pour les utilisateurs avancés uniquement.
page_size : Définissez le nombre de résultats à récupérer immédiatement à partir de ftrack.session : joignez un objet de session à la requête. Faites de la déclaration une sous-requête à utiliser dans .in_() .
Cela garantit qu'il y a toujours un "Select parmi" dans le cadre de la déclaration. La définition manuelle du paramètre d'attribut remplacera toutes les projections existantes.
Utilisé pour créer de nouvelles entités.
from ftrack_query import create
stmt = create ( entity ). values (...) L'appel session.execute(stmt) renverra l'entité créée.
Valeurs pour créer l'entité avec.
Utilisé pour lancer des valeurs de mise à jour sur plusieurs entités. Ceci est construit sur la méthode select , il contient donc beaucoup des mêmes méthodes.
from ftrack_query import update
stmt = update ( entity ). where (...). values (...) L'appel session.execute(stmt) renvoie le nombre d'entités trouvées et mises à jour.
Filtrez quoi mettre à jour.
Valeurs à mettre à jour sur l'entité.
Utilisé pour supprimer des entités. Ceci est construit sur la méthode select , il contient donc beaucoup des mêmes méthodes.
from ftrack_query import delete
stmt = delete ( entity ). where (...). options ( remove_components = True ) L'appel session.execute(stmt) renverra le nombre d'entités supprimées.
Filtrez quoi mettre à jour.
remove_components : supprimez n'importe quelle entité Component de chaque Location qui le contenant avant d'être supprimé. Ceci n'est pas activé par défaut car il ne peut pas être annulé. L'objet Comparison est conçu pour convertir les données en une chaîne. Il contient un large éventail d'opérateurs qui peuvent être utilisés sur n'importe quel type de données, y compris d'autres objets Comparison . La fonction attr est un raccourci vers cela.
Toute comparaison peut être inversée avec la fonction ~ préfixe ou 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)Comparaisons simples.
Effectuez un chèque pour vérifier si un attribut correspond à des résultats.
Cela peut accepter une sous-requête telle .in_('select id from table where x is y') , ou une liste d'éléments comme .in_(['x', 'y']) .
Vérifiez si une chaîne est contenue dans la requête. Utilisez un signe en pourcentage comme joker si vous utilisez like ou not_like ; Les autres sont des raccourcis et le font automatiquement.
Tester les relations scalaires et de collecte.
Tester contre les dates. L'utilisation d'objets arrow est recommandé.
# 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 ))