Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

Ftrack: Hierarchical attributes are queried properly #2682

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
import json
import collections
import ftrack_api
from openpype_modules.ftrack.lib import ServerAction
from openpype_modules.ftrack.lib import (
ServerAction,
query_custom_attributes
)


class PushHierValuesToNonHier(ServerAction):
Expand Down Expand Up @@ -51,10 +54,6 @@ class PushHierValuesToNonHier(ServerAction):
" from CustomAttributeConfiguration"
" where key in ({})"
)
cust_attr_value_query = (
"select value, entity_id from CustomAttributeValue"
" where entity_id in ({}) and configuration_id in ({})"
)

# configurable
settings_key = "sync_hier_entity_attributes"
Expand Down Expand Up @@ -344,33 +343,22 @@ def get_hier_values(
all_ids_with_parents.add(parent_id)
_entity_id = parent_id

joined_entity_ids = self.join_query_keys(all_ids_with_parents)

hier_attr_ids = self.join_query_keys(
tuple(hier_attr["id"] for hier_attr in hier_attrs)
)
hier_attr_ids = tuple(hier_attr["id"] for hier_attr in hier_attrs)
hier_attrs_key_by_id = {
hier_attr["id"]: hier_attr["key"]
for hier_attr in hier_attrs
}
call_expr = [{
"action": "query",
"expression": self.cust_attr_value_query.format(
joined_entity_ids, hier_attr_ids
)
}]
if hasattr(session, "call"):
[values] = session.call(call_expr)
else:
[values] = session._call(call_expr)

values_per_entity_id = {}
for entity_id in all_ids_with_parents:
values_per_entity_id[entity_id] = {}
for key in hier_attrs_key_by_id.values():
values_per_entity_id[entity_id][key] = None

for item in values["data"]:
values = query_custom_attributes(
session, all_ids_with_parents, hier_attr_ids, True
)
for item in values:
entity_id = item["entity_id"]
key = hier_attrs_key_by_id[item["configuration_id"]]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ class PushFrameValuesToTaskEvent(BaseEvent):
" (object_type_id in ({}) or is_hierarchical is true)"
)

cust_attr_query = (
"select value, entity_id from ContextCustomAttributeValue "
"where entity_id in ({}) and configuration_id in ({})"
)

_cached_task_object_id = None
_cached_interest_object_ids = None
_cached_user_id = None
Expand Down Expand Up @@ -273,16 +268,23 @@ def process_task_parent_change(
hier_attr_ids.append(attr_id)

conf_ids = list(hier_attr_ids)
task_conf_ids = []
for key, attr_id in task_attrs.items():
attr_key_by_id[attr_id] = key
nonhier_id_by_key[key] = attr_id
conf_ids.append(attr_id)
task_conf_ids.append(attr_id)

# Query custom attribute values
# - result does not contain values for all entities only result of
# query callback to ftrack server
result = query_custom_attributes(
session, conf_ids, whole_hierarchy_ids
session, list(hier_attr_ids), whole_hierarchy_ids, True
)
result.extend(
query_custom_attributes(
session, task_conf_ids, whole_hierarchy_ids, False
)
)

# Prepare variables where result will be stored
Expand Down Expand Up @@ -547,7 +549,7 @@ def finalize_attribute_changes(
)
attr_ids = set(attr_id_to_key.keys())

current_values_by_id = self.current_values(
current_values_by_id = self.get_current_values(
session, attr_ids, entity_ids, task_entity_ids, hier_attrs
)

Expand Down Expand Up @@ -642,27 +644,17 @@ def filter_changes(

return interesting_data, changed_keys_by_object_id

def current_values(
def get_current_values(
self, session, attr_ids, entity_ids, task_entity_ids, hier_attrs
):
current_values_by_id = {}
if not attr_ids or not entity_ids:
return current_values_by_id
joined_conf_ids = self.join_query_keys(attr_ids)
joined_entity_ids = self.join_query_keys(entity_ids)

call_expr = [{
"action": "query",
"expression": self.cust_attr_query.format(
joined_entity_ids, joined_conf_ids
)
}]
if hasattr(session, "call"):
[values] = session.call(call_expr)
else:
[values] = session._call(call_expr)

for item in values["data"]:
values = query_custom_attributes(
session, attr_ids, entity_ids, True
)
for item in values:
entity_id = item["entity_id"]
attr_id = item["configuration_id"]
if entity_id in task_entity_ids and attr_id in hier_attrs:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def _update_in_links(self, session, ftrack_ids, project_id):

def _get_mongo_ids_by_ftrack_ids(self, session, attr_id, ftrack_ids):
output = query_custom_attributes(
session, [attr_id], ftrack_ids
session, [attr_id], ftrack_ids, True
)
mongo_id_by_ftrack_id = {}
for item in output:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

from openpype_modules.ftrack.lib import (
get_openpype_attr,
query_custom_attributes,
CUST_ATTR_ID_KEY,
CUST_ATTR_AUTO_SYNC,

Expand Down Expand Up @@ -2130,22 +2131,12 @@ def process_hier_cleanup(self):
for key in hier_cust_attrs_keys:
configuration_ids.add(hier_attr_id_by_key[key])

entity_ids_joined = self.join_query_keys(cust_attrs_ftrack_ids)
attributes_joined = self.join_query_keys(configuration_ids)

queries = [{
"action": "query",
"expression": (
"select value, entity_id, configuration_id"
" from CustomAttributeValue "
"where entity_id in ({}) and configuration_id in ({})"
).format(entity_ids_joined, attributes_joined)
}]

if hasattr(self.process_session, "call"):
[values] = self.process_session.call(queries)
else:
[values] = self.process_session._call(queries)
values = query_custom_attributes(
self.process_session,
configuration_ids,
cust_attrs_ftrack_ids,
True
)

ftrack_project_id = self.cur_project["id"]

Expand All @@ -2170,7 +2161,7 @@ def process_hier_cleanup(self):

# PREPARE DATA BEFORE THIS
avalon_hier = []
for item in values["data"]:
for item in values:
value = item["value"]
if value is None:
continue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ class CleanHierarchicalAttrsAction(BaseAction):
" from TypedContext where project_id is \"{}\""
)
cust_attr_query = (
"select value, entity_id from CustomAttributeValue "
"where entity_id in ({}) and configuration_id is \"{}\""
"select value, entity_id from CustomAttributeValue"
" where entity_id in ({}) and configuration_id is \"{}\""
)
settings_key = "clean_hierarchical_attr"

Expand Down Expand Up @@ -65,17 +65,14 @@ def launch(self, session, entities, event):
)
)
configuration_id = attr["id"]
call_expr = [{
"action": "query",
"expression": self.cust_attr_query.format(
values = session.query(
self.cust_attr_query.format(
entity_ids_joined, configuration_id
)
}]

[values] = self.session.call(call_expr)
).all()

data = {}
for item in values["data"]:
for item in values:
value = item["value"]
if value is None:
data[item["entity_id"]] = value
Expand All @@ -90,10 +87,10 @@ def launch(self, session, entities, event):
len(data), configuration_key
))
for entity_id, value in data.items():
entity_key = collections.OrderedDict({
"configuration_id": configuration_id,
"entity_id": entity_id
})
entity_key = collections.OrderedDict((
("configuration_id", configuration_id),
("entity_id", entity_id)
))
session.recorded_operations.push(
ftrack_api.operation.DeleteEntityOperation(
"CustomAttributeValue",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,8 @@ def convert_mongo_id_to_hierarchical(
}

cust_attr_query = (
"select value, entity_id from ContextCustomAttributeValue "
"where configuration_id is {}"
"select value, entity_id from CustomAttributeValue"
" where configuration_id is {}"
)
for attr_def in object_type_attrs:
attr_ent_type = attr_def["entity_type"]
Expand All @@ -328,21 +328,14 @@ def convert_mongo_id_to_hierarchical(
self.log.debug((
"Converting Avalon MongoID attr for Entity type \"{}\"."
).format(entity_type_label))

call_expr = [{
"action": "query",
"expression": cust_attr_query.format(attr_def["id"])
}]
if hasattr(session, "call"):
[values] = session.call(call_expr)
else:
[values] = session._call(call_expr)

for value in values["data"]:
table_values = collections.OrderedDict({
"configuration_id": hierarchical_attr["id"],
"entity_id": value["entity_id"]
})
values = session.query(
cust_attr_query.format(attr_def["id"])
).all()
for value in values:
table_values = collections.OrderedDict([
("configuration_id", hierarchical_attr["id"]),
("entity_id", value["entity_id"])
])

session.recorded_operations.push(
ftrack_api.operation.UpdateEntityOperation(
Expand Down
7 changes: 4 additions & 3 deletions openpype/modules/default_modules/ftrack/ftrack_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,10 @@ def on_project_anatomy_save(
# TODO add add permissions check
# TODO add value validations
# - value type and list items
entity_key = collections.OrderedDict()
entity_key["configuration_id"] = configuration["id"]
entity_key["entity_id"] = project_id
entity_key = collections.OrderedDict([
("configuration_id", configuration["id"]),
("entity_id", project_id)
])

session.recorded_operations.push(
ftrack_api.operation.UpdateEntityOperation(
Expand Down
Loading