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

Commit

Permalink
Merge pull request #2682 from pypeclub/bugfix/OP-2610_Ftrack-hiearchi…
Browse files Browse the repository at this point in the history
…cal-attributes-sync-uses-default-values

Ftrack: Hierarchical attributes are queried properly
  • Loading branch information
iLLiCiTiT authored Feb 9, 2022
2 parents 5330735 + 0716c1c commit 94754e0
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 170 deletions.
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

0 comments on commit 94754e0

Please sign in to comment.