Ftrack Query عبارة عن غلاف موجه للكائنات على واجهة برمجة تطبيقات Ftrack. على الرغم من أن بناء جملة الاستعلام الافتراضي قوي ، إلا أنه يعتمد تمامًا على النص ، بحيث يكون من الصعب إنشاء الاستعلامات الديناميكية. تدعم هذه الوحدة و / أو المشغلين مع مقارنات متداخلة.
يوصى أولاً بقراءة https://ftrack-python-api.readthedocs.io/en/stable/tutorial.html لفهم أساسي لكيفية عمل واجهة برمجة تطبيقات Ftrack.
pip install ftrack_query
بدلاً من كتابة سلسلة الاستعلام بأكملها في وقت واحد ، يتم إنشاء "عبارة" ( مثل stmt = select('Task') ) ، ويمكن بناء الاستعلام عن طريق طرق الاتصال مثل .where() و .populate() في البيان.
يتم دعم جميع أساليب CRUD ( create ، select ، update ، delete ) ، ولكن الوظيفة الرئيسية مصممة للاستخدام مع select . تم تصميم العبارات مع بناء جملة مماثل إلى واجهة برمجة التطبيقات الرئيسية بحيث يكون من السهل الانتقال بين الاثنين.
لاحظ أن هذا متوافق تمامًا إلى الوراء ، لذلك لا تحتاج إلى إعادة كتابة الاستعلامات الموجودة.
المثال أدناه مخصص للاستعلامات الأساسية للغاية:
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 (...) QueryResult .first() session.execute(stmt) .one() .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 (...) 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 : قم بإزالة أي كيان 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 ))