@@ -1664,7 +1664,17 @@ class Job(Base, JobLike, UsesCreateAndUpdateTime, Dictifiable, Serializable):
16641664 back_populates="job"
16651665 )
16661666
1667- dict_collection_visible_keys = ["id", "state", "exit_code", "update_time", "create_time", "galaxy_version"]
1667+ dict_collection_visible_keys = [
1668+ "id",
1669+ "state",
1670+ "exit_code",
1671+ "update_time",
1672+ "create_time",
1673+ "galaxy_version",
1674+ "tool_id",
1675+ "tool_version",
1676+ "history_id",
1677+ ]
16681678 dict_element_visible_keys = [
16691679 "id",
16701680 "state",
@@ -1675,6 +1685,9 @@ class Job(Base, JobLike, UsesCreateAndUpdateTime, Dictifiable, Serializable):
16751685 "command_version",
16761686 "copied_from_job_id",
16771687 "user_id",
1688+ "tool_id",
1689+ "tool_version",
1690+ "history_id",
16781691 ]
16791692
16801693 _numeric_metric = JobMetricNumeric
@@ -2210,9 +2223,6 @@ def to_dict(self, view="collection", system_details=False):
22102223 rval = super().to_dict(view="collection")
22112224 else:
22122225 rval = super().to_dict(view=view)
2213- rval["tool_id"] = self.tool_id
2214- rval["tool_version"] = self.tool_version
2215- rval["history_id"] = self.history_id
22162226 if system_details or view == "admin_job_list":
22172227 # System level details that only admins should have.
22182228 rval["external_id"] = self.job_runner_external_id
@@ -2848,6 +2858,17 @@ def job_list(self):
28482858 .all()
28492859 )
28502860
2861+ def get_job_attributes(self, attributes: list[str]):
2862+ session = required_object_session(self)
2863+ targets = [getattr(Job.table.columns, attr) for attr in attributes]
2864+ stmt = (
2865+ select(*targets)
2866+ .select_from(Job)
2867+ .join(ImplicitCollectionJobsJobAssociation, Job.id == ImplicitCollectionJobsJobAssociation.job_id)
2868+ .where(ImplicitCollectionJobsJobAssociation.implicit_collection_jobs_id == self.id)
2869+ )
2870+ return session.execute(stmt)
2871+
28512872 def _serialize(self, id_encoder, serialization_options):
28522873 rval = dict_for(
28532874 self,
@@ -10169,6 +10190,15 @@ def _serialize(self, id_encoder, serialization_options):
1016910190
1017010191 return step_attrs
1017110192
10193+ def get_jobs_dict(self):
10194+ if self.implicit_collection_jobs:
10195+ result = self.implicit_collection_jobs.get_job_attributes(Job.dict_collection_visible_keys)
10196+ return [{"model_class": "Job", **row._mapping} for row in result]
10197+ elif self.job:
10198+ return [self.job.to_dict()]
10199+ else:
10200+ return []
10201+
1017210202 def to_dict(self, view="collection", value_mapper=None):
1017310203 rval = super().to_dict(view=view, value_mapper=value_mapper)
1017410204 rval["order_index"] = self.workflow_step.order_index
@@ -10177,9 +10207,7 @@ def to_dict(self, view="collection", value_mapper=None):
1017710207 # Following no longer makes sense...
1017810208 # rval['state'] = self.job.state if self.job is not None else None
1017910209 if view == "element":
10180- jobs = []
10181- for job in self.jobs:
10182- jobs.append(job.to_dict())
10210+ jobs = self.get_jobs_dict()
1018310211
1018410212 outputs = {}
1018510213 for output_assoc in self.output_datasets:
0 commit comments