FTRACK-Abfrage ist eine objektorientierte Wrapper über der Ftrack-API. Während die Standard -Abfrage -Syntax leistungsstark ist, ist sie vollständig textbasiert, sodass dynamische Abfragen schwierig zu konstruieren sind. Dieses Modul unterstützt und / oder Betreiber mit verschachtelten Vergleiche.
Es wird empfohlen, zuerst https://ftrack-python-api.readthedocs.io/en/stable/tutorial.html zu lesen, um ein grundlegendes Verständnis dafür zu erhalten, wie die FTRACK-API funktioniert.
pip install ftrack_query
Anstatt die gesamte Abfrage -Zeichenfolge gleichzeitig zu schreiben, wird eine "Anweisung" konstruiert ( z. B. stmt = select('Task') ), und die Abfrage kann durch Aufrufen von Methoden wie .where() und .populate() in der Anweisung erstellt werden.
Die CRUD -Methoden werden alle unterstützt ( create , select , update , delete ), aber die Hauptfunktionalität ist für die Verwendung mit select konzipiert. Die Aussagen werden mit einer ähnlichen Syntax wie der Haupt -API erstellt, sodass es unkompliziert sein sollte, zwischen beiden zu wechseln.
Beachten Sie, dass dies vollständig rückwärtskompatibel ist, sodass vorhandene Fragen nicht umgeschrieben werden müssen.
Das folgende Beispiel ist für sehr grundlegende Abfragen:
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 ()Für ein viel komplexeres Beispiel:
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 ()Das Ereignissystem verwendet eine etwas andere Abfragesprache.
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 () Beachten Sie, dass attr() and_() und or_() sowohl in ftrack_query als auch in ftrack_query.event vorhanden sind. Diese sind nicht austauschbar. Wenn beide benötigt werden, importieren Sie event und verwenden Sie dies als Namespace.
Hauptsitzung von ftrack_api.Session .
Melden Sie sich mehreren Vergleichen an.
Verknüpfungen werden mit & und | versehen ( zB attr(a).contains(b) & attr(x).contains(y) ).
Gegehen Sie die Eingangsvergleiche um.
Eine Abkürzung ist mit ~ ( z. B. ~attr(x).contains(y) ).
Wird zum Erstellen der Abfragezeichenfolge verwendet.
from ftrack_query import select
stmt = select ( entity ). where (...). populate (...) Aufrufen von session.execute(stmt) wird das Abfrage ausführen und das QueryResult -Objekt von Ftrack zurückgeben, von dem .one() , .first() oder .all() aufgerufen werden kann. Alternativ kann dies durch die Verwendung der session.select(entity) verwendet werden, dann kann dies übersprungen werden.
Filtern Sie das Ergebnis.
Die Verwendung von Schlüsselwörtern ist der schnellste Weg, wie .where(first_name='Peter', last_name='Hunt') Bei etwas Komplexerem als Gleichstellungsprüfungen wird attr() empfohlen, wie .where(attr('project.metadata').any(attr('key') != 'disabled'))
Vorab-Entitätsattribute.
Ein Beispiel, um den Namen eines jeden Benutzers durchzusetzen, wäre es eine gute Idee .populate('first_name', 'last_name') Ohne das würde 2 separate Abfragen pro Benutzer dauern, die als N+1 -Abfrageproblem bekannt sind.
Sortieren Sie die Ergebnisse nach einem Attribut.
Das Attribut und die Reihenfolge können im Format attr('name').desc() oder als rohe Zeichenfolge wie der name descending werden. Die Bestellung wird standardmäßig ascending , wenn nicht angegeben.
Die Sortierrichtung umkehren.
Beschränken Sie die Anzahl der Ergebnisse auf einen bestimmten Wert.
HINWEIS: Dies ist unvereinbar mit dem Aufrufen von .first() oder .one() .
Wenden Sie bei der Verwendung eines Limits einen Offset auf das zurückgegebene Ergebnis an.
Nur für fortgeschrittene Benutzer.
page_size : Stellen Sie die Anzahl der Ergebnisse fest, die sofort von Ftrack abgerufen werden sollen.session : Fügen Sie der Abfrage ein Sitzungsobjekt bei. Machen Sie die Anweisung zu einer Unterabfrage für die Verwendung innerhalb von .in_() .
Dies stellt sicher, dass es immer ein "Auswahlauswahl" als Teil der Aussage gibt. Wenn Sie den Attributparameter manuell einstellen, überschreiben Sie alle vorhandenen Projektionen.
Wird zur Erstellung neuer Einheiten verwendet.
from ftrack_query import create
stmt = create ( entity ). values (...) Rufen Sie session.execute(stmt) zurück.
Werte zum Erstellen der Entität mit.
Wird verwendet, um die Aktualisierungswerte auf mehreren Entitäten zu stapeln. Dies wird aus der select erstellt, sodass viele der gleichen Methoden enthält.
from ftrack_query import update
stmt = update ( entity ). where (...). values (...) Calling session.execute(stmt) wird zurückgeben, wie viele Unternehmen gefunden und aktualisiert wurden.
Filtern Sie, was zu aktualisieren ist.
Werte zur Aktualisierung der Entität.
Wird verwendet, um Entitäten zu löschen. Dies wird aus der select erstellt, sodass viele der gleichen Methoden enthält.
from ftrack_query import delete
stmt = delete ( entity ). where (...). options ( remove_components = True ) Calling session.execute(stmt) wird zurückgeben, wie viele Unternehmen gelöscht wurden.
Filtern Sie, was zu aktualisieren ist.
remove_components : Entfernen Sie eine Component von jedem Location , der sie enthält, bevor sie gelöscht wird. Dies ist standardmäßig nicht aktiviert, da es nicht zurückgerollt werden kann. Das Comparison ist so konzipiert, dass Daten in eine Zeichenfolge umwandelt werden. Es enthält eine breite Palette von Operatoren, die gegen jeden Datentyp verwendet werden können, einschließlich anderer Comparison . Die Funktion attr ist eine Abkürzung dazu.
Jeder Vergleich kann mit dem ~ Präfix oder der not_ -Funktion umgekehrt werden.
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)Einfache Vergleiche.
Führen Sie eine Überprüfung durch, um zu überprüfen, ob ein Attribut mit den Ergebnissen übereinstimmt.
Dies kann eine Unterabfrage wie .in_('select id from table where x is y') oder eine Liste von Elementen wie .in_(['x', 'y']) akzeptieren kann.
Überprüfen Sie, ob eine Zeichenfolge in der Abfrage enthalten ist. Verwenden Sie ein prozentuales Zeichen als Wildcard, wenn Sie like oder not_like verwendet werden. Der Rest sind Verknüpfungen und tun dies automatisch.
Test gegen Skalar- und Sammlungsbeziehungen.
Testen Sie gegen Daten. Die Verwendung von arrow wird empfohlen.
# 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 ))