diff --git a/SAS/ResourceAssignment/ResourceAssignmentDatabase/radb.py b/SAS/ResourceAssignment/ResourceAssignmentDatabase/radb.py index b7f094b258992cdfcbc2f459273a881e5312684f..ab3fc24ae7183b3183eed7c5ce72e8479128c037 100644 --- a/SAS/ResourceAssignment/ResourceAssignmentDatabase/radb.py +++ b/SAS/ResourceAssignment/ResourceAssignmentDatabase/radb.py @@ -95,18 +95,21 @@ class RADatabase: # keep track if last/current transaction was already committed or rolled_back self.committed = False self.rolled_back = False + query_log_line = self._queryAsSingleLine(query, qargs) + + if self.log_queries: + logger.debug('executing query: %s', query_log_line) + self.cursor.execute(query, qargs) if self.log_queries: elapsed = datetime.utcnow() - start elapsed_ms = 1000.0 * totalSeconds(elapsed) logger.info('executed query in %.1fms%s yielding %s rows: %s', elapsed_ms, ' (SLOW!)' if elapsed_ms > 250 else '', # for easy log grep'ing - self.cursor.rowcount, - self._queryAsSingleLine(query, qargs)) + self.cursor.rowcount, query_log_line) break except (psycopg2.OperationalError, AttributeError) as e: - if isinstance(e, psycopg2.OperationalError): - logger.error("psycopg operational error: %s", str(e)) + logger.error("psycopg operational error while executing query: '%s' error: '%s'", query_log_line, str(e)) self._connect() if self.conn: @@ -114,7 +117,7 @@ class RADatabase: time.sleep(i*i) except (psycopg2.IntegrityError, psycopg2.ProgrammingError, psycopg2.InternalError, psycopg2.DataError) as e: self._log_database_notifications() - logger.error("Rolling back query=\'%s\' due to error: \'%s\'" % (self._queryAsSingleLine(query, qargs), e)) + logger.error("Rolling back query=\'%s\' due to error: \'%s\'" % (query_log_line, e)) self.rollback() return [] # TODO: instead of doing a "silent" rollback and continue, we should raise an RADBError. @@ -1459,9 +1462,15 @@ class RADatabase: fields.append('user_id') values.append(user_id) - query = '''UPDATE resource_allocation.resource_claim - SET ({fields}) = ({value_placeholders})'''.format(fields=', '.join(fields), - value_placeholders=', '.join('%s' for x in fields)) + fields_str=', '.join(fields) + value_placeholders_str=', '.join('%s' for x in fields) + if len(fields) > 1: + # for updating multiple columns, wrap the columns and values in parentheses + fields_str = "(%s)" % fields_str + value_placeholders_str = "(%s)" % value_placeholders_str + + query = '''UPDATE resource_allocation.resource_claim SET {fields} = {value_placeholders}'''.format( + fields=fields_str, value_placeholders=value_placeholders_str) if where_resource_claim_ids is None and where_task_ids is None: raise ValueError('please provide either "where_resource_claim_ids" and/or "where_task_ids" argument for updateResourceClaims') @@ -1481,9 +1490,16 @@ class RADatabase: if isinstance(where_task_ids, int): # just a single id conditions.append('task_id = %s') condition_values.append(where_task_ids) - elif len(where_task_ids): #assume a list/enumerable of id's - conditions.append('task_id in %s') - condition_values.append(tuple(where_task_ids)) + elif isinstance(where_task_ids, collections.abc.Iterable): #assume a list/enumerable of id's + if len(where_task_ids) == 1: + # faster + conditions.append('task_id = %s') + condition_values.append(where_task_ids[0]) + else: + conditions.append('task_id in %s') + condition_values.append(tuple(where_task_ids)) + else: + raise RADBError("Invalid type for 'where_task_ids': %s %s" % (type(where_task_ids), where_task_ids)) if where_resource_types is not None: if isinstance(where_resource_types, str) or isinstance(where_resource_types, int):