Package helpers :: Module RollbackIngest
[hide private]

Source Code for Module helpers.RollbackIngest

  1  #! /usr/bin/env python 
  2  #------------------------------------------------------------------------------ 
  3  # $Id: RollbackIngest.py 7794 2011-01-20 19:58:40Z RossCollins $ 
  4  """ 
  5     Rolls-back a CU3 (only for now) ingest quickly by ignoring cascading deletes 
  6     to detections. 
  7   
  8     @author: R.S. Collins 
  9     @org:    WFAU, IfA, University of Edinburgh 
 10  """ 
 11  #------------------------------------------------------------------------------ 
 12  from __future__      import division, print_function 
 13  from future_builtins import map 
 14   
 15  from   wsatools.CLI                 import CLI 
 16  import wsatools.CSV                     as csv 
 17  from   wsatools.DbConnect.CuSession import CuSession 
 18  import wsatools.DbConnect.DbConstants   as dbc 
 19  from   wsatools.DbConnect.DbSession import SelectSQL 
 20  import wsatools.DbConnect.Schema        as schema 
 21  from   wsatools.Logger              import Logger 
 22  import wsatools.Utilities               as utils 
 23  #------------------------------------------------------------------------------ 
 24   
25 -class IngestRollbacker(CuSession):
26 """ Rolls-back a CU3 (only for now) ingest quickly by ignoring cascading 27 deletes to detections. 28 """ 29 #-------------------------------------------------------------------------- 30 # Private class parameters for this procedure - should not be altered 31 32 _autoCommit = True # Overrides CuSession default 33 comment = "Rolling back CU3 ingest of cuEventID(s) %s" 34 35 _missingConstraints = False #: Are constraints currently missing from db? 36 37 #-------------------------------------------------------------------------- 38 # Public member variable default values - set from command-line options 39 40 #: Comma-separated list of cuEventIDs to roll back. 41 cuEventIDs = "0" 42 #: Ignore database schema discrepancies? 43 ignoreWarnings = False 44 45 #-------------------------------------------------------------------------- 46
47 - def _onRun(self):
48 """ Update the database. 49 """ 50 eventIDstr = utils.numberRange(map(int, csv.values(self.cuEventIDs))) 51 self.comment = IngestRollbacker.comment % eventIDstr 52 53 Logger.addMessage("Parsing table schema...") 54 55 scripts = set(self.programme.getAttr('catalogueSchema')) 56 scripts.discard(dbc.charDefault()) 57 tableSchema = set() 58 for progScript in scripts: 59 tableSchema.update(schema.parseTables(progScript)) 60 61 Logger.addMessage("Checking that the database schema agree...") 62 try: 63 self.archive.checkSchema(tableSchema) 64 except schema.MismatchError as error: 65 if self.ignoreWarnings: 66 Logger.addMessage("<WARNING> %s" % error) 67 tableSchema -= error.brokenTables 68 else: 69 raise IngestRollbacker.CuError(error) 70 71 cu3Tables = ["Multiframe", "MultiframeDetector", "CurrentAstrometry", 72 "ProgrammeFrame"] 73 74 foreignKeys = set() 75 for tableName in cu3Tables: 76 for table in tableSchema: 77 for con in table.constraints: 78 if (type(con) is schema.ForeignKeyConstraint 79 and con.referenceTable==tableName): 80 con.withOpts = "NOCHECK" 81 foreignKeys.add(con) 82 83 Logger.addMessage("Dropping foreign key constraints...") 84 self._missingConstraints = True 85 self.archive.dropObjects(foreignKeys) 86 87 Logger.addMessage("Rolling back cuEventID(s): %s" % eventIDstr) 88 89 # Provenance.combiFrameID is handled via cascading deletes, but still 90 # need to manually remove the component entries. 91 Logger.addMessage("Removing Provenance component entries...") 92 Logger.addMessage("%s rows deleted." % 93 self.archive.delete("Provenance", "multiframeID IN (%s)" % 94 SelectSQL("multiframeID", "Multiframe", 95 "cuEventID IN (%s)" % self.cuEventIDs))) 96 97 # Relies on cascade deletes to rollback all CU3 ingests 98 Logger.addMessage("Rolling back metadata ingests...") 99 Logger.addMessage("%s rows deleted." % 100 self.archive.delete("Multiframe", 101 "cuEventID IN (%s)" % self.cuEventIDs)) 102 103 Logger.addMessage("Reapplying foreign key constraints...") 104 self.archive.createObjects(foreignKeys, haltOnError=False) 105 self._missingConstraints = False
106 107 #-------------------------------------------------------------------------- 108
109 - def _onException(self):
110 """ Warn about any missing foreign key constraints. 111 """ 112 super(IngestRollbacker, self)._onException() 113 if self._missingConstraints: 114 Logger.addMessage("<IMPORTANT> %s database has been left with " 115 "missing foreign key constraints." % self.database)
116 117 #------------------------------------------------------------------------------ 118 119 if __name__ == "__main__": 120 CLI.progArgs["comment"] = IngestRollbacker.comment 121 CLI.progArgs.append(CLI.Argument("event_IDs", IngestRollbacker.cuEventIDs, 122 isValOK=lambda x: all(cid.isdigit() for cid in csv.values(x)))) 123 CLI.progOpts.append(CLI.Option('i', "ignore", "ignore schema warnings")) 124 125 cli = CLI(IngestRollbacker.__name__, "$Revision: 7794 $", __doc__) 126 Logger.addMessage(cli.getProgDetails()) 127 Logger.isVerbose = False 128 129 if CLI.isConfirmed("This will rollback metadata only for cuEventID(s) " 130 + utils.numberRange(map(int, csv.values(cli.getArg("event_IDs"))))): 131 132 IngestRollbacker.cuEventIDs = cli.getArg("event_IDs") 133 IngestRollbacker.ignoreWarnings = cli.getOpt("ignore") 134 IngestRollbacker(cli=cli).run() 135 136 #------------------------------------------------------------------------------ 137