- Timestamp:
- Mar 5, 2012, 5:19:48 PM (14 years ago)
- Location:
- branches/meh_branches/ppstack_test
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
ippToPsps/jython/ipptopspsdb.py (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/meh_branches/ppstack_test
- Property svn:mergeinfo changed
-
branches/meh_branches/ppstack_test/ippToPsps/jython/ipptopspsdb.py
r32122 r33415 17 17 Constructor 18 18 ''' 19 def __init__(self, logger, doc): 20 super(IppToPspsDb, self).__init__(logger, doc, "ipptopspsdatabase") 21 22 ''' 23 Creates a new batch 24 ''' 25 def createNewBatch(self, batchType, stageID, survey, dvoDb, datastoreProduct): 26 27 sql = "INSERT INTO batch ( \ 28 batch_type, \ 29 stage_id, \ 30 survey, \ 31 dvo_db, \ 32 datastore_product \ 33 ) VALUES ( \ 34 '" + batchType + "', \ 35 " + str(stageID) + ", \ 36 '" + survey + "', \ 37 '" + dvoDb + "', \ 38 '" + datastoreProduct + "' \ 39 )" 40 41 self.execute(sql) 42 43 sql = "SELECT MAX(batch_id) FROM batch" 44 45 batchID = -1; 46 47 try: 48 rs = self.executeQuery(sql) 49 rs.first() 50 batchID = rs.getInt(1) 51 except: 52 self.logger.exception("Unable to get batch ID") 53 54 self.logger.debug("Created new batch in ippToPsps database with batchID = %d" % batchID) 55 56 return batchID; 57 58 ''' 59 Returns a list of processed batch IDs that are merged but not yet deleted 60 ''' 61 def getMergedButNotDeletedBatchIDs(self, epoch, dvoGpc1Label): 19 def __init__(self, logger, config): 20 super(IppToPspsDb, self).__init__(logger, config, "ipptopspsdatabase") 21 22 self.MAX_FAILS = 5 23 24 ''' 25 Returns a list of merged batch IDs that are merged but not yet deleted 26 ''' 27 def getMergedButNotDeletedBatchIDs(self, batchType, epoch, dvoGpc1Label, column): 62 28 63 29 sql = "SELECT DISTINCT batch_id \ 64 30 FROM batch \ 65 31 WHERE timestamp > '" + epoch + "' \ 66 AND dvo_db = '" + dvoGpc1Label + "' \ 67 AND merged \ 68 AND !deleted" 32 AND batch_type = '" + batchType + "' \ 33 AND dvo_db = '" + dvoGpc1Label + "' \ 34 AND merged = 1 \ 35 AND " + column + " = 0" 36 37 ids = [] 38 try: 39 rs = self.executeQuery(sql) 40 while (rs.next()): ids.append(rs.getInt(1)) 41 rs.close() 42 except: 43 self.logger.exception("Can't query for merged batch ids in ipptopsps Db") 44 45 self.logger.debug("Found %d merged but un-deleted items" % len(ids)) 46 47 return ids 48 49 ''' 50 Returns a list of batch IDs marked as 'purged' but not yet deleted 51 ''' 52 def getPurgedButNotDeletedBatchIDs(self, batchType, epoch, dvoGpc1Label, column): 53 54 sql = "SELECT DISTINCT batch_id \ 55 FROM batch \ 56 WHERE timestamp > '" + epoch + "' \ 57 AND batch_type = '" + batchType + "' \ 58 AND dvo_db = '" + dvoGpc1Label + "' \ 59 AND purged = 1 \ 60 AND " + column + " = 0" 61 62 ids = [] 63 try: 64 rs = self.executeQuery(sql) 65 while (rs.next()): ids.append(rs.getInt(1)) 66 rs.close() 67 except: 68 self.logger.exception("Can't query for merged batch ids in ipptopsps Db") 69 70 71 self.logger.debug("Found %d merged but un-deleted items" % len(ids)) 72 73 return ids 74 75 ''' 76 Returns a list of processed batch IDs that have been loaded to the ODM but not yet deleted 77 ''' 78 def getLoadedToODMButNotDeletedBatchIDs(self, batchType, epoch, dvoGpc1Label, column): 79 80 sql = "SELECT DISTINCT batch_id \ 81 FROM batch \ 82 WHERE timestamp > '" + epoch + "' \ 83 AND batch_type = '" + batchType + "' \ 84 AND dvo_db = '" + dvoGpc1Label + "' \ 85 AND (loaded_to_ODM = -1 OR merge_worthy = 1) \ 86 AND " + column + " = 0" 87 88 ids = [] 89 try: 90 rs = self.executeQuery(sql) 91 while (rs.next()): ids.append(rs.getInt(1)) 92 rs.close() 93 except: 94 self.logger.exception("Can't query for merged batch ids in ipptopsps Db") 95 96 self.logger.debug("Found %d merged but un-deleted items" % len(ids)) 97 98 return ids 99 100 ''' 101 Returns a list of merged batch IDs that are not deleted from local disk 102 ''' 103 def getMergedButNotDeletedFromLocalDisk(self, batchType, epoch, dvoGpc1Label): 104 return self.getMergedButNotDeletedBatchIDs(batchType, epoch, dvoGpc1Label, "deleted_local") 105 106 ''' 107 Returns a list of processed batch IDs that are loaded to the ODM, but not deleted from local disk 108 ''' 109 def getLoadedToODMButNotDeletedFromLocalDisk(self, batchType, epoch, dvoGpc1Label): 110 return self.getLoadedToODMButNotDeletedBatchIDs(batchType, epoch, dvoGpc1Label, "deleted_local") 111 112 ''' 113 Returns a list of processed batch IDs that are loaded to the ODM, but not deleted from datastore 114 ''' 115 def getLoadedToODMButNotDeletedFromDatastore(self, batchType, epoch, dvoGpc1Label): 116 return self.getLoadedToODMButNotDeletedBatchIDs(batchType, epoch, dvoGpc1Label, "deleted_datastore") 117 118 ''' 119 Returns a list of processed batch IDs that are loaded to the ODM, but not deleted from DXLayer 120 ''' 121 def getLoadedToODMButNotDeletedFromDXLayer(self, batchType, epoch, dvoGpc1Label): 122 return self.getLoadedToODMButNotDeletedBatchIDs(batchType, epoch, dvoGpc1Label, "deleted_dxlayer") 123 124 ''' 125 Returns a list of purged batch IDs that not deleted from local disk 126 ''' 127 def getPurgedButNotDeletedFromLocalDisk(self, batchType, epoch, dvoGpc1Label): 128 return self.getPurgedButNotDeletedBatchIDs(batchType, epoch, dvoGpc1Label, "deleted_local") 129 130 ''' 131 Returns a list of purged batch IDs that are not deleted from datastore 132 ''' 133 def getPurgedButNotDeletedFromDatastore(self, batchType, epoch, dvoGpc1Label): 134 return self.getPurgedButNotDeletedBatchIDs(batchType, epoch, dvoGpc1Label, "deleted_datastore") 135 136 137 ''' 138 Returns a list of processed batch IDs that are not loaded to the datastore 139 NB we have a date constraint here because, before this time, it is possible that 140 a test batch would be labelled as processed but not loaded to datastore, and we would NOT 141 want to load a test batch to PSPS 142 143 We also check that these batches are more than 4 HOURs old, so that we don't attempt to 144 publish something simulataneously with the client that it producing it 145 ''' 146 def getProcessedButFailedDatastoreBatchIDs(self, epoch, dvoGpc1Label, batchType): 147 148 sql = "SELECT DISTINCT batch_id \ 149 FROM batch \ 150 WHERE timestamp > '" + epoch + "' \ 151 AND batch_type = '" + batchType + "' \ 152 AND dvo_db = '" + dvoGpc1Label + "' \ 153 AND processed = 1\ 154 AND loaded_to_datastore != 1 \ 155 AND timestamp > '2011-10-27' \ 156 AND timestamp < now() - INTERVAL 4 HOUR" 69 157 70 158 ids = [] … … 74 162 ids.append(rs.getInt(1)) 75 163 except: 76 self.logger.exception("Can't query for merged batch ids inipptopsps Db")164 self.logger.exception("Can't query for processed batch ids not loaded to datastore ipptopsps Db") 77 165 78 166 rs.close() 79 167 80 self.logger.debug("Found %d merged but un-deleted items" % len(ids)) 81 82 return ids 83 84 ''' 85 Returns a list of processed batch IDs that are not yet merged for this epoch and dvo label 86 ''' 87 def getProcessedButUnmergedBatchIDs(self, epoch, dvoGpc1Label): 88 89 sql = "SELECT DISTINCT batch_id \ 168 self.logger.debug("Found %d processed but-not-on-datastore items" % len(ids)) 169 170 return ids 171 172 ''' 173 Returns a list of processed batch IDs that are not yet loaded to the ODM 174 NOTE we exclude batches already deleted from the datastore, as sometimes we delete stuff prior to loading to ODM if there is a known problem with the batch 175 ''' 176 def getUnloadedBatchIDs(self, epoch, dvoGpc1Label, batchType): 177 178 sql = "SELECT batch_id \ 90 179 FROM batch \ 91 180 WHERE timestamp > '" + epoch + "' \ 92 181 AND dvo_db = '" + dvoGpc1Label + "' \ 93 AND loaded_to_datastore \ 94 AND !merged" 182 AND loaded_to_datastore = 1 \ 183 AND batch_type = '" + batchType + "' \ 184 AND loaded_to_ODM = 0 \ 185 AND deleted_datastore = 0" 95 186 96 187 ids = [] … … 100 191 ids.append(rs.getInt(1)) 101 192 except: 102 self.logger.exception("Can't query for processed batch ids in ipptopsps Db")193 self.logger.exception("Can't query for unloaded batch ids in ipptopsps Db") 103 194 104 195 rs.close() 105 196 106 self.logger.debug("Found %d processed and un-merged items" % len(ids)) 107 108 return ids 109 110 ''' 111 Returns a list of IDs for this batch type, epoch and dvo label (i.e. either 112 cam_ids or stack_ids) for which the spefified column is true (=1) 113 ''' 114 def getStageIDs(self, batchType, epoch, dvoGpc1Label, column): 115 116 sql = "SELECT DISTINCT stage_id \ 197 self.logger.debug("Found %d unloaded items" % len(ids)) 198 199 return ids 200 201 ''' 202 Returns a list of processed batch IDs that are not yet merge_worthy and that have not failed to load 203 NOTE we exclude batches already deleted from the datastore, as sometimes we delete stuff prior to loading to ODM if there is a known problem with the batch 204 ''' 205 def getUnmergeWorthyBatchIDs(self, epoch, dvoGpc1Label, batchType): 206 207 sql = "SELECT batch_id \ 208 FROM batch \ 209 WHERE timestamp > '" + epoch + "' \ 210 AND dvo_db = '" + dvoGpc1Label + "' \ 211 AND loaded_to_datastore = 1 \ 212 AND batch_type = '" + batchType + "' \ 213 AND merge_worthy = 0 \ 214 AND loaded_to_ODM != -1 \ 215 AND deleted_datastore = 0" 216 217 ids = [] 218 try: 219 rs = self.executeQuery(sql) 220 while (rs.next()): 221 ids.append(rs.getInt(1)) 222 except: 223 self.logger.exception("Can't query for un-mergeworthy batch ids in ipptopsps Db") 224 225 rs.close() 226 227 self.logger.debug("Found %d unloaded items" % len(ids)) 228 229 return ids 230 231 ''' 232 Returns a list of processed batch IDs that are merge_worthy, but not yet merged, for this epoch and dvo label 233 ''' 234 def getUnmergedBatchIDs(self, epoch, dvoGpc1Label, batchType): 235 236 sql = "SELECT batch_id \ 237 FROM batch \ 238 WHERE timestamp > '" + epoch + "' \ 239 AND dvo_db = '" + dvoGpc1Label + "' \ 240 AND merge_worthy = 1 \ 241 AND batch_type = '" + batchType + "' \ 242 AND merged != 1" 243 244 ids = [] 245 try: 246 rs = self.executeQuery(sql) 247 while (rs.next()): 248 ids.append(rs.getInt(1)) 249 except: 250 self.logger.exception("Can't query for unmerged batch ids in ipptopsps Db") 251 252 rs.close() 253 254 self.logger.debug("Found %d un-merged items" % len(ids)) 255 256 return ids 257 258 ''' 259 Returns a list of batch IDs for this epoch and dvo label for which the specified column is set to value 260 ''' 261 def getBatchIDs(self, epoch, dvoGpc1Label, column, value): 262 263 sql = "SELECT DISTINCT batch_id \ 264 FROM batch \ 265 WHERE timestamp > '" + epoch + "' \ 266 AND dvo_db = '" + dvoGpc1Label + "' \ 267 AND " + column + " = " + str(value) 268 269 ids = [] 270 try: 271 rs = self.executeQuery(sql) 272 while (rs.next()): 273 ids.append(rs.getInt(1)) 274 except: 275 self.logger.exception("Can't query for batch ids with " + column + " = " + str(value) + " in ipptopsps Db") 276 277 rs.close() 278 279 self.logger.debug("Found %d batches with %s = %d" % (len(ids), column, value)) 280 281 return ids 282 283 ''' 284 Returns the total detections published to the datastore for this epoch, dvo label and batch type 285 ''' 286 def getTotalDetectionsPublished(self, batchType, epoch, dvoGpc1Label): 287 288 sql = "SELECT SUM(total_detections) \ 117 289 FROM batch \ 118 290 WHERE batch_type = '" + batchType + "' \ 119 291 AND timestamp > '" + epoch + "' \ 120 292 AND dvo_db = '" + dvoGpc1Label + "' \ 121 AND " + column + " = 1" 293 AND processed = 1 \ 294 AND loaded_to_datastore = 1" 295 296 total = -1 297 try: 298 rs = self.executeQuery(sql) 299 rs.first() 300 total = rs.getLong(1) 301 except: 302 self.logger.exception("Can't query for total detections published") 303 304 rs.close() 305 306 self.logger.debug("Found %d detections" % total) 307 308 return total 309 310 ''' 311 Returns a list of IDs for this batch type, epoch and dvo label (i.e. either 312 cam_ids or stack_ids) for which the specified column is set to value 313 ''' 314 def getStageIDs(self, batchType, epoch, dvoGpc1Label, column, value): 315 316 sql = "SELECT DISTINCT stage_id \ 317 FROM batch \ 318 WHERE batch_type = '" + batchType + "' \ 319 AND timestamp > '" + epoch + "' \ 320 AND dvo_db = '" + dvoGpc1Label + "' \ 321 AND " + column + " = " + str(value) 122 322 123 323 ids = [] … … 127 327 ids.append(rs.getInt(1)) 128 328 except: 129 self.logger.exception("Can't query for ids with " + column + " = 1in ipptopsps Db")329 self.logger.exception("Can't query for ids with " + column + " = " + str(value) + " in ipptopsps Db") 130 330 131 331 rs.close() … … 136 336 137 337 ''' 338 Series of getter methods that utilise getBatchIDs() method above 339 ''' 340 def getloadedToDatastoreBatchIDs(self, epoch, dvoGpc1Label): 341 return self.getBatchIDs(epoch, dvoGpc1Label, "loaded_to_datastore", 1) 342 def getFailedLoadedToODMBatchIDs(self, epoch, dvoGpc1Label): 343 return self.getBatchIDs(epoch, dvoGpc1Label, "loaded_to_ODM", -1) 344 345 ''' 346 TODO remove these 138 347 Series of getter methods that utilise getStageIDs() method above 139 348 ''' 140 349 def getProcessedIDs(self, batchType, epoch, dvoGpc1Label): 141 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "processed") 142 def getloadedToDatastoreIDs(self, batchType, epoch, dvoGpc1Label): 143 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "loaded_to_datastore") 350 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "processed", 1) 351 def getFailedProcessedIDs(self, batchType, epoch, dvoGpc1Label): 352 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "processed", -1) 353 def getLoadedToDatastoreIDs(self, batchType, epoch, dvoGpc1Label): 354 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "loaded_to_datastore", 1) 355 def getFailedLoadedToDatastoreIDs(self, batchType, epoch, dvoGpc1Label): 356 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "loaded_to_datastore", -1) 144 357 def getLoadedToODMIDs(self, batchType, epoch, dvoGpc1Label): 145 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "loaded_to_ODM") 146 def getMergeWothyIDs(self, batchType, epoch, dvoGpc1Label): 147 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "merge_worthy") 358 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "loaded_to_ODM", 1) 359 def getFailedLoadedToODMIDs(self, batchType, epoch, dvoGpc1Label): 360 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "loaded_to_ODM", -1) 361 def getMergeWorthyIDs(self, batchType, epoch, dvoGpc1Label): 362 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "merge_worthy", 1) 363 def getFailedMergeWorthyIDs(self, batchType, epoch, dvoGpc1Label): 364 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "merge_worthy", -1) 148 365 def getMergedIDs(self, batchType, epoch, dvoGpc1Label): 149 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "merged") 366 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "merged", 1) 367 def getFailedMergedIDs(self, batchType, epoch, dvoGpc1Label): 368 return self.getStageIDs(batchType, epoch, dvoGpc1Label, "merged", -1) 369 370 ''' 371 Returns a list of stages 372 ''' 373 def getStages(self): 374 return ['processed', 'loaded_to_datastore', 'loaded_to_ODM', 'merge_worthy', 'deleted_datastore', 'deleted_dxlayer', 'merged', 'deleted_local' ] 375 376 ''' 377 Returns a count of batches processed in the specified time period. 378 ''' 379 def countBatchesInLastPeriod(self, batchType, epoch, dvoGpc1Label, interval): 380 381 sql = "SELECT COUNT(batch_id) \ 382 FROM batch \ 383 WHERE batch_type = '" + batchType + "' \ 384 AND processed = 1 \ 385 AND timestamp > '" + epoch + "' \ 386 AND dvo_db = '" + dvoGpc1Label + "' \ 387 AND timestamp BETWEEN now() - INTERVAL " + interval + " AND now()" 388 389 try: 390 rs = self.executeQuery(sql) 391 if rs.first(): return rs.getInt(1) 392 except: 393 self.logger.exception("Unable to count batches in interval") 394 return 0 150 395 151 396 ''' … … 155 400 def getTimeOfLastBatchPublished(self, batchType, epoch, dvoGpc1Label): 156 401 157 minutes = None158 159 sql = "SELECT TIMESTAMPDIFF( MINUTE, timestamp, now()) \402 seconds = None 403 404 sql = "SELECT TIMESTAMPDIFF(SECOND, timestamp, now()) \ 160 405 FROM batch \ 161 406 WHERE batch_type = '" + batchType + "' \ 162 AND loaded_to_datastore \407 AND loaded_to_datastore = 1 \ 163 408 AND timestamp > '" + epoch + "' \ 164 409 AND dvo_db = '" + dvoGpc1Label + "' \ … … 167 412 try: 168 413 rs = self.executeQuery(sql) 169 if rs.first(): minutes = rs.getFloat(1)414 if rs.first(): seconds = rs.getFloat(1) 170 415 except: 171 416 self.logger.exception("Unable to get last batch published") 172 417 173 if not minutes: return "Never" 174 418 if not seconds: return "Never" 419 420 minutes = seconds/60.0 175 421 hours = minutes/60.0 176 days = float(hours)/24.0 177 weeks = float(days)/7.0 178 179 if minutes < 60: return "%.1f minutes ago" % minutes 422 days = hours/24.0 423 weeks = days/7.0 424 425 if seconds < 60: return "%.1f secs ago" % seconds 426 elif minutes < 60: return "%.1f mins ago" % minutes 180 427 elif hours < 48: return "%.1f hours ago" % hours 181 428 elif days < 7: return "%.1f days ago" % days … … 183 430 184 431 ''' 185 TODO186 '''187 def getBatchesPerDay(self, batchType, startTime, endTime=""):188 189 bph = self.getBatchesPerHour(batchType, startTime, endTime)190 return bph * 24191 192 '''193 TODO194 '''195 def getBatchesPerHour(self, batchType, startTime, endTime=""):196 197 bpm = self.getBatchesPerMinute(batchType, startTime, endTime)198 return bpm * 60199 200 '''201 TODO202 '''203 def getAverageTimePerBatch(self, batchType, startTime, endTime=""):204 205 sql = "SELECT (TIMESTAMPDIFF(MINUTE, min(timestamp), max(timestamp)) / COUNT(*)) \206 FROM batch \207 WHERE timestamp > '" + startTime + "' and batch_type = '" + batchType + "'"208 209 try:210 rs = self.executeQuery(sql)211 rs.first()212 time = rs.getDouble(1)213 except:214 self.logger.exception("Unable to get batches per minute")215 216 return time217 218 '''219 TODO220 '''221 def getBatchesPerMinute(self, batchType, startTime, endTime=""):222 223 sql = "SELECT (count(*) / TIMESTAMPDIFF(MINUTE, min(timestamp), max(timestamp)) ) \224 FROM batch \225 WHERE timestamp > '" + startTime + "' and batch_type = '" + batchType + "'"226 227 try:228 rs = self.executeQuery(sql)229 rs.first()230 bpm = rs.getDouble(1)231 except:232 self.logger.exception("Unable to get batches per minute")233 234 return bpm235 236 '''237 432 Updates min/max object ID on this table and batch 238 433 ''' 239 def update MinMaxObjID(self, batchID, minObjID, maxObjID):434 def updateDetectionStats(self, batchID, minObjID, maxObjID, totalDetections): 240 435 241 436 sql = "UPDATE batch SET \ 242 437 min_obj_id = " + str(minObjID) + ", \ 243 max_obj_id = " + str(maxObjID) + " \ 438 max_obj_id = " + str(maxObjID) + ", \ 439 total_detections = " + str(totalDetections) + " \ 244 440 WHERE batch_id = " + str(batchID) 245 441 … … 257 453 self.execute(sql) 258 454 259 260 455 ''' 261 456 Updates batch processed field … … 265 460 266 461 ''' 267 Updates batch deleted field 268 ''' 269 def updateDeleted(self, batchID, deleted): 270 self.updateColumn(batchID, "deleted", deleted) 462 Updates batch deleted local field 463 ''' 464 def updateDeletedLocal(self, batchID, value): 465 self.updateColumn(batchID, "deleted_local", value) 466 467 ''' 468 Updates batch deleted datastore field 469 ''' 470 def updateDeletedDatastore(self, batchID, value): 471 self.updateColumn(batchID, "deleted_datastore", value) 472 473 ''' 474 Updates batch deleted dxlayer field 475 ''' 476 def updateDeletedDxlayer(self, batchID, value): 477 self.updateColumn(batchID, "deleted_dxlayer", value) 271 478 272 479 ''' … … 290 497 291 498 ''' 292 Have we already processed and published this batch?293 ''' 294 def alreadyProcessed(self, stage_id):499 Is someone processing this item right now? Checks whether this was attempted within the last 2 HOUR 500 ''' 501 def processingNow(self, batchType, stage_id, epoch, dvoGpc1Label): 295 502 296 503 sql = "SELECT COUNT(*) \ 297 504 FROM batch \ 298 505 WHERE stage_id = " + str(stage_id) + " \ 299 AND processed \ 300 AND loaded_to_datastore" 506 AND batch_type = '" + batchType + "' \ 507 AND dvo_db = '" + dvoGpc1Label + "' \ 508 AND timestamp BETWEEN now() - INTERVAL 4 HOUR AND now()" 301 509 302 510 try: … … 304 512 rs.first() 305 513 if rs.getInt(1) > 0: 306 self.logger. error("Batch with stage_id = "+str(stage_id) + " has already been processed and published to datastore")514 self.logger.debugPair(str(stage_id) + " is already being processed", "skipping") 307 515 return True 308 516 else: 309 517 return False 310 518 except: 519 self.logger.exception("Unable to check whether this batch is being processed") 520 521 ''' 522 Gets the batch type of this batch 523 ''' 524 def getBatchType(self, batch_id): 525 526 sql = "SELECT batch_type \ 527 FROM batch \ 528 WHERE batch_id = " + str(batch_id) 529 530 batch_type = "NA" 531 try: 532 rs = self.executeQuery(sql) 533 rs.first() 534 batch_type = rs.getString(1) 535 except: 311 536 self.logger.exception("Unable to check whether this batch has already been processed") 312 537 538 return batch_type 539 540 ''' 541 Have we already processed this stage_id? 542 ''' 543 def alreadyProcessed(self, batchType, stage_id, epoch, dvoGpc1Label): 544 545 sql = "SELECT COUNT(*) \ 546 FROM batch \ 547 WHERE stage_id = " + str(stage_id) + " \ 548 AND batch_type = '" + batchType + "' \ 549 AND timestamp > '" + epoch + "' \ 550 AND dvo_db = '" + dvoGpc1Label + "' \ 551 AND processed = 1" 552 553 try: 554 rs = self.executeQuery(sql) 555 rs.first() 556 if rs.getInt(1) > 0: 557 self.logger.debugPair(str(stage_id) + " has already been published", "skipping") 558 return True 559 else: 560 return False 561 except: 562 self.logger.exception("Unable to check whether this batch has already been processed") 563 564 ''' 565 Has this stage_id consistently failed to process? 566 ''' 567 def consistentlyFailed(self, batchType, stage_id, epoch, dvoGpc1Label): 568 569 sql = "SELECT COUNT(*) \ 570 FROM batch \ 571 WHERE stage_id = " + str(stage_id) + " \ 572 AND batch_type = '" + batchType + "' \ 573 AND timestamp > '" + epoch + "' \ 574 AND dvo_db = '" + dvoGpc1Label + "' \ 575 AND processed = -1" 576 577 try: 578 rs = self.executeQuery(sql) 579 rs.first() 580 if rs.getInt(1) >= self.MAX_FAILS: 581 self.logger.errorPair(str(stage_id) + " has failed %d times" % self.MAX_FAILS, "skipping") 582 return True 583 else: 584 return False 585 except: 586 self.logger.exception("Unable to check whether this batch has consistently failed") 587 588 ''' 589 Returns a list of stage_ids that have failed the max number of times 590 ''' 591 def getConsistentlyFailedIDs(self, batchType, epoch, dvoGpc1Label): 592 593 sql = "SELECT DISTINCT stage_id, COUNT(stage_id) AS numoccur \ 594 FROM batch \ 595 WHERE batch_type = '" + batchType + "' \ 596 AND timestamp > '" + epoch + "' \ 597 AND dvo_db = '" + dvoGpc1Label + "' \ 598 AND processed = -1 \ 599 GROUP BY stage_id HAVING numoccur >= " + str(self.MAX_FAILS) 600 601 ids = [] 602 try: 603 rs = self.executeQuery(sql) 604 while (rs.next()): 605 ids.append(rs.getInt(1)) 606 except: 607 self.logger.exception("Can't query for consistantly failed ids in ipptopsps Db") 608 609 rs.close() 610 611 self.logger.debug("Found %d consistantly failed stage_ids for batch type='%s'" % (len(ids), batchType)) 612 613 return ids 614 615 ''' 616 Locks the batch table. This will wait if the lock is held by someone else 617 ''' 618 def lockBatchTable(self): 619 self.lockTable("batch") 620 621 ''' 622 Creates a new batch. This is done with a locked table in order that no two clients can start work on the same item 623 ''' 624 def createNewBatch(self, batchType, stageID, config): 625 626 batchID = -1; 627 628 if config.force or \ 629 (not self.alreadyProcessed(batchType, stageID, config.epoch, config.dvoLabel) \ 630 and not self.processingNow(batchType, stageID, config.epoch, config.dvoLabel) \ 631 and not self.consistentlyFailed(batchType, stageID, config.epoch, config.dvoLabel)): 632 633 sql = "INSERT INTO batch ( \ 634 batch_type, \ 635 stage_id, \ 636 survey, \ 637 dvo_db, \ 638 datastore_product \ 639 ) VALUES ( \ 640 '" + batchType + "', \ 641 " + str(stageID) + ", \ 642 '" + config.survey + "', \ 643 '" + config.dvoLabel + "', \ 644 '" + config.datastoreProduct + "' \ 645 )" 646 647 self.execute(sql) 648 649 sql = "SELECT MAX(batch_id) FROM batch" 650 651 try: 652 rs = self.executeQuery(sql) 653 rs.first() 654 batchID = rs.getInt(1) 655 self.logger.debug("Created new batch in ippToPsps database with batchID = %d" % batchID) 656 except: 657 self.logger.exception("Unable to get batch ID") 658 batchID = -1 659 660 return batchID; 313 661 314 662 … … 346 694 self.execute(sql) 347 695 696 ''' 697 Resets a batch ready for re-loading to the datastore 698 ''' 699 def resetBatch(self, batchID): 700 701 sql = "UPDATE batch SET \ 702 loaded_to_datastore = 0, \ 703 loaded_to_ODM = 0, \ 704 merge_worthy = 0, \ 705 merged = 0, \ 706 deleted_datastore = 0, \ 707 deleted_dxlayer = 0, \ 708 comment = 'This batch was reset, ready for re-load to datastore' \ 709 WHERE batch_id = " + str(batchID) 710 711 self.execute(sql) 712 713 ''' 714 Remove client 715 ''' 716 def removeClient(self, host, pid): 717 self.execute("DELETE FROM clients WHERE host = '" + host + "' AND pid = " + str(pid)) 718 719 ''' 720 Insert client 721 ''' 722 def insertClient(self, type, host, pid, config): 723 self.execute("INSERT INTO clients (timestamp, type, host, pid, config) VALUES (now(), '" + type + "', '" + host + "', " + str(pid) + ", '" + config + "')") 724 725 ''' 726 Update clients, or inserts it for the first time 727 ''' 728 def updateClient(self, type, host, pid, config): 729 730 try: 731 self.insertClient(type, host, pid, config) 732 except: 733 self.execute("UPDATE clients SET timestamp = now() WHERE host = '" + host + "' AND pid = " + str(pid)) 734 735 ''' 736 Is this client paused? 737 ''' 738 def isPaused(self, host, pid): 739 return self.getClientsColumnBoolean("paused", host, pid) 740 741 ''' 742 Is this client killed? 743 ''' 744 def isKilled(self, host, pid): 745 return self.getClientsColumnBoolean("killed", host, pid) 746 747 ''' 748 Returns boolean value for this column in clients table 749 ''' 750 def getClientsColumnBoolean(self, col, host, pid): 751 752 sql = "SELECT " + col + " \ 753 FROM clients \ 754 WHERE host = '" + host + "' AND pid = " + str(pid) 755 756 try: 757 rs = self.executeQuery(sql) 758 rs.first() 759 if rs.getInt(1) == 1: return True 760 else: return False 761 except: 762 self.logger.exception("Unable to check whether " + col + " is true or false in clients table") 763 764 return False 765 766 767 ''' 768 Populates Config object 769 ''' 770 def readConfig(self, host, pid): 771 772 # first get config defined for this client 773 sql = "SELECT config \ 774 FROM clients \ 775 WHERE host = '" + host + "' \ 776 AND pid = " + str(pid) 777 778 try: 779 rs = self.executeQuery(sql) 780 rs.first() 781 self.config.name = rs.getString(1) 782 except: 783 self.logger.errorPair("No config set for", "%s (pid=%d)" % (host, pid)) 784 self.config.isLoaded = False 785 return False 786 787 # now load that config 788 sql = "SELECT \ 789 datastore_product, \ 790 datastore_type, \ 791 datastore_publish, \ 792 dvo_label, \ 793 dvo_location, \ 794 min_ra, \ 795 max_ra, \ 796 min_dec, \ 797 max_dec, \ 798 box_size, \ 799 base_path, \ 800 data_release, \ 801 delete_local, \ 802 delete_datastore, \ 803 delete_dxlayer, \ 804 epoch, \ 805 survey, \ 806 psps_survey, \ 807 queue_P2, \ 808 queue_ST \ 809 FROM config \ 810 WHERE name = '" + self.config.name + "'" 811 812 self.config.batchTypes = [] 813 try: 814 rs = self.executeQuery(sql) 815 rs.first() 816 self.config.datastoreProduct = rs.getString(1) 817 self.config.datastoreType = rs.getString(2) 818 if rs.getInt(3) == 1: self.config.datastorePublishing = True 819 else: self.config.datastorePublishing = False 820 self.config.dvoLabel = rs.getString(4) 821 self.config.dvoLocation = rs.getString(5) 822 self.config.minRa = rs.getDouble(6) 823 self.config.maxRa = rs.getDouble(7) 824 self.config.minDec = rs.getDouble(8) 825 self.config.maxDec = rs.getDouble(9) 826 827 self.config.boxSize = rs.getDouble(10) 828 self.config.halfBox = self.config.boxSize/2.0 829 self.config.boxSizeWithBorder = self.config.boxSize + (self.config.BORDER * 2) 830 831 self.config.basePath = rs.getString(11) 832 self.config.dataRelease = rs.getInt(12) 833 self.config.deleteLocal = rs.getInt(13) 834 self.config.deleteDatastore = rs.getInt(14) 835 self.config.deleteDxLayer = rs.getInt(15) 836 self.config.epoch = rs.getString(16) 837 self.config.survey = rs.getString(17) 838 self.config.pspsSurvey = rs.getString(18) 839 if rs.getInt(19) == 1: self.config.batchTypes.append("P2") 840 if rs.getInt(20) == 1: self.config.batchTypes.append("ST") 841 self.config.force = False # TODO 842 self.config.test = False # TODO 843 self.config.isLoaded = True 844 except: 845 self.logger.errorPair("Could not read config with name", self.config.name) 846 self.config.isLoaded = False 847 848 return self.config.isLoaded 849 850 ''' 851 Gets id of box with these coords 852 ''' 853 def getBoxId(self, config, ra, dec, boxSide): 854 855 sql = "SELECT id FROM box \ 856 WHERE config = '" + config + "' \ 857 AND ra_center = " + str(ra) + " \ 858 AND dec_center = " + str(dec) + " \ 859 AND box_side = " + str(boxSide) 860 861 id = -1 862 try: 863 rs = self.executeQuery(sql) 864 rs.first() 865 id = rs.getInt(1) 866 except: 867 pass 868 869 return id 870 871 872 ''' 873 Remove all boxes and associated ids in pending table 874 ''' 875 def removeAllBoxes(self, config): 876 self.execute("DELETE FROM box WHERE config = '" + config + "'") 877 878 ''' 879 Removes a box and it's associated ids in the pending table 880 ''' 881 def removeBox(self, config, ra, dec, boxSide): 882 self.execute("DELETE FROM box \ 883 WHERE config = '" + config + "' \ 884 AND ra_center = " + str(ra) + " \ 885 AND dec_center = " + str(dec) + " \ 886 AND box_side = " + str(boxSide)) 887 888 ''' 889 Inserts new box into box table. If it already exisits, it returns existing box id 890 ''' 891 def insertBox(self, config, ra, dec, boxSide): 892 893 id = self.getBoxId(config, ra, dec, boxSide) 894 895 # does not already exists so insert 896 if id < 0: 897 898 sql = "INSERT INTO box \ 899 (config, ra_center, dec_center, box_side) \ 900 VALUES \ 901 ('" + config + "', " + str(ra) + ", " + str(dec) + ", " + str(boxSide) + ")" 902 903 self.execute(sql) 904 id = self.getBoxId(config, ra, dec, boxSide) 905 906 return id 907 908 ''' 909 Inserts new box ids into the pending table 910 ''' 911 def insertPending(self, box_id, batchType, ids): 912 913 # first delete old pending items 914 self.execute("DELETE FROM pending WHERE box_id = " + str(box_id)) 915 916 for id in ids: 917 sql = "INSERT INTO pending \ 918 (box_id, batch_type, stage_id) \ 919 VALUES \ 920 (" + str(box_id) + ", '" + batchType + "', " + str(id) + ")" 921 922 self.execute(sql) 923 924 ''' 925 Returns ids for all boxes with pending items 926 ''' 927 def getBoxIds(self, config): 928 929 sql = "SELECT DISTINCT id \ 930 FROM box \ 931 JOIN pending ON (id = box_id) \ 932 WHERE config = '" + config + "' \ 933 ORDER BY ra_center, dec_center" 934 935 ids = [] 936 try: 937 rs = self.executeQuery(sql) 938 while (rs.next()): ids.append(rs.getInt(1)) 939 rs.close() 940 except: 941 self.logger.errorPair("Can't get boxes", sql) 942 943 return ids 944 945 ''' 946 Returns dimensions of this box 947 ''' 948 def getBoxDimensions(self, boxId): 949 950 sql = "SELECT ra_center, dec_center, box_side FROM box WHERE id = " + str(boxId) 951 952 boxDim = {} 953 rs = self.executeQuery(sql) 954 rs.first() 955 956 boxDim['RA'] = rs.getFloat(1) 957 boxDim['DEC'] = rs.getFloat(2) 958 boxDim['SIDE'] = rs.getFloat(3) 959 960 return boxDim 961 962 ''' 963 Returns ids for pending items in this box for this batch type 964 ''' 965 def getPendingIds(self, boxId, batchType): 966 967 sql = "SELECT stage_id FROM pending WHERE batch_type = '" + batchType + "' AND box_id = " + str(boxId) 968 969 ids = [] 970 try: 971 rs = self.executeQuery(sql) 972 while (rs.next()): ids.append(rs.getInt(1)) 973 rs.close() 974 except: 975 self.logger.errorPair("Can't get ids from this box", sql) 976 977 return ids 978 979 ''' 980 Returns max number of pensing items in a box for this config 981 ''' 982 def getMaxPendingInBox(self, config): 983 984 sql = "SELECT MAX(pending) \ 985 FROM (SELECT COUNT(stage_id) AS pending \ 986 FROM pending \ 987 JOIN box ON (id = box_id) \ 988 WHERE config = '" + config + "' \ 989 GROUP BY box_id) AS t" 990 991 try: 992 rs = self.executeQuery(sql) 993 rs.first() 994 return rs.getInt(1) 995 except: 996 self.logger.errorPair("Could not count max pending", sql) 997 return 100 998 999 ''' 1000 Writes density-plot data to file for pending stuff over sky for given config 1001 ''' 1002 def createPendingDensityPlotData(self, config, DATFILE): 1003 1004 sql = "SELECT ra_center, dec_center, COUNT(stage_id) \ 1005 FROM box \ 1006 LEFT JOIN pending ON (id = box_id) \ 1007 WHERE config = '" + config + "' \ 1008 GROUP BY id \ 1009 ORDER BY ra_center, dec_center" 1010 1011 try: 1012 rs = self.executeQuery(sql) 1013 while (rs.next()): 1014 print >> DATFILE, rs.getFloat(1), rs.getFloat(2), rs.getInt(3) 1015 rs.close() 1016 except: 1017 self.logger.errorPair("Can't get density plot data", sql) 348 1018 349 1019 ''' … … 352 1022 def __del__(self): 353 1023 354 self.logger.debug("IppToPspsDb Des structor")1024 self.logger.debug("IppToPspsDb Destructor") 355 1025 self.stmt.close() 356 1026 self.con.close()
Note:
See TracChangeset
for help on using the changeset viewer.
