diff --git a/specifyweb/backend/stored_queries/execution.py b/specifyweb/backend/stored_queries/execution.py index cde46621e8e..679cad49c71 100644 --- a/specifyweb/backend/stored_queries/execution.py +++ b/specifyweb/backend/stored_queries/execution.py @@ -1086,6 +1086,10 @@ def build_query( ) if field is None: + # Keep the result column in place when a displayed tree rank is + # missing, while omitting its filter and sort behavior. + if fs.display: + query = query.add_columns(sql.null()) continue formatted_field = None diff --git a/specifyweb/backend/stored_queries/query_construct.py b/specifyweb/backend/stored_queries/query_construct.py index 614ee449d43..f56a1f8d636 100644 --- a/specifyweb/backend/stored_queries/query_construct.py +++ b/specifyweb/backend/stored_queries/query_construct.py @@ -29,6 +29,7 @@ def __new__(cls, *args, **kwargs): def handle_tree_field(self, node, table, tree_rank: TreeRankQuery, next_join_path, current_field_spec: QueryFieldSpec): query = self + query_before_tree_joins = query if query.collection is None: # Not sure it makes sense to query across collections raise AssertionError( f"No Collection found in Query for {table}", @@ -70,7 +71,13 @@ def handle_tree_field(self, node, table, tree_rank: TreeRankQuery, next_join_pat if (tree_rank.treedef_id is None or tree_rank.treedef_id == treedef_id) ] if tup[1] is not None] - assert len(treedefs_with_ranks) >= 1, "Didn't find the tree rank across any tree" + if not treedefs_with_ranks: + logger.warning( + "Didn't find tree rank %r across any %s tree; skipping field", + tree_rank.name, + table.name, + ) + return query_before_tree_joins, None, None, table treedefitem_params = [treedefitem_id for (_, treedefitem_id) in treedefs_with_ranks] diff --git a/specifyweb/backend/stored_queries/queryfieldspec.py b/specifyweb/backend/stored_queries/queryfieldspec.py index 3ce298fdf38..74fc05350f4 100644 --- a/specifyweb/backend/stored_queries/queryfieldspec.py +++ b/specifyweb/backend/stored_queries/queryfieldspec.py @@ -534,6 +534,8 @@ def add_to_query( # print "is auditlog obj format field = " + str(self.is_auditlog_obj_format_field(formatauditobjs)) # print "############################################################################" query, orm_field, field, table = self.add_spec_to_query(query, formatter) + if orm_field is None: + return query, None, None return self.apply_filter( query, orm_field,