@logExceptions(_LOGGER)<EOL><INDENT>@g_retrySQL<EOL>def jobInfoWithModels(self, jobID):<DEDENT>
<EOL>combinedResults = None<EOL>with ConnectionFactory.get() as conn:<EOL><INDENT>query = '<STR_LIT:U+0020>'.join([<EOL>'<STR_LIT>' % (self.jobsTableName, self.modelsTableName),<EOL>'<STR_LIT>' % self.jobsTableName,<EOL>'<STR_LIT>' % self.modelsTableName,<EOL>'<STR_LIT>'])<EOL>conn.cursor.execute(query, (jobID,))<EOL>if conn.cursor.rowcount > <NUM_LIT:0>:<EOL><INDENT>combinedResults = [<EOL>ClientJobsDAO._combineResults(<EOL>result, self._jobs.jobInfoNamedTuple,<EOL>self._models.modelInfoNamedTuple<EOL>) for result in conn.cursor.fetchall()]<EOL><DEDENT><DEDENT>if combinedResults is not None:<EOL><INDENT>return combinedResults<EOL><DEDENT>raise RuntimeError("<STR_LIT>" % (jobID))<EOL>
Get all info about a job, with model details, if available.

        Parameters:
        ----------------------------------------------------------------
        job:    jobID of the job to query
        retval: A sequence of two-tuples if the jobID exists in the jobs
                 table (exeption is raised if it doesn't exist). Each two-tuple
                 contains an instance of jobInfoNamedTuple as the first element and
                 an instance of modelInfoNamedTuple as the second element. NOTE: In
                 the case where there are no matching model rows, a sequence of one
                 two-tuple will still be returned, but the modelInfoNamedTuple
                 fields will be None, and the jobInfoNamedTuple fields will be
                 populated.