diff --git a/openpype/modules/ftrack/lib/__init__.py b/openpype/modules/ftrack/lib/__init__.py index ce6d5284b6..9dc2d67279 100644 --- a/openpype/modules/ftrack/lib/__init__.py +++ b/openpype/modules/ftrack/lib/__init__.py @@ -13,7 +13,8 @@ from .custom_attributes import ( default_custom_attributes_definition, app_definitions_from_app_manager, tool_definitions_from_app_manager, - get_openpype_attr + get_openpype_attr, + query_custom_attributes ) from . import avalon_sync @@ -37,6 +38,7 @@ __all__ = ( "app_definitions_from_app_manager", "tool_definitions_from_app_manager", "get_openpype_attr", + "query_custom_attributes", "avalon_sync", diff --git a/openpype/modules/ftrack/lib/custom_attributes.py b/openpype/modules/ftrack/lib/custom_attributes.py index f6b82c90b1..53facd4ab2 100644 --- a/openpype/modules/ftrack/lib/custom_attributes.py +++ b/openpype/modules/ftrack/lib/custom_attributes.py @@ -81,3 +81,60 @@ def get_openpype_attr(session, split_hierarchical=True, query_keys=None): return custom_attributes, hier_custom_attributes return custom_attributes + + +def join_query_keys(keys): + """Helper to join keys to query.""" + return ",".join(["\"{}\"".format(key) for key in keys]) + + +def query_custom_attributes(session, conf_ids, entity_ids, table_name=None): + """Query custom attribute values from ftrack database. + + Using ftrack call method result may differ based on used table name and + version of ftrack server. + + Args: + session(ftrack_api.Session): Connected ftrack session. + conf_id(list, set, tuple): Configuration(attribute) ids which are + queried. + entity_ids(list, set, tuple): Entity ids for which are values queried. + table_name(str): Table nam from which values are queried. Not + recommended to change until you know what it means. + """ + output = [] + # Just skip + if not conf_ids or not entity_ids: + return output + + if table_name is None: + table_name = "ContextCustomAttributeValue" + + # Prepare values to query + attributes_joined = join_query_keys(conf_ids) + attributes_len = len(conf_ids) + + # Query values in chunks + chunk_size = int(5000 / attributes_len) + # Make sure entity_ids is `list` for chunk selection + entity_ids = list(entity_ids) + for idx in range(0, len(entity_ids), chunk_size): + entity_ids_joined = join_query_keys( + entity_ids[idx:idx + chunk_size] + ) + + call_expr = [{ + "action": "query", + "expression": ( + "select value, entity_id from {}" + " where entity_id in ({}) and configuration_id in ({})" + ).format(table_name, entity_ids_joined, attributes_joined) + }] + if hasattr(session, "call"): + [result] = session.call(call_expr) + else: + [result] = session._call(call_expr) + + for item in result["data"]: + output.append(item) + return output