source: TI01-discovery-Ingest/trunk/v4.3.0/ingestAutomation-upgrade/OAIBatch/PostgresDAO.py @ 8026

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI01-discovery-Ingest/trunk/v4.3.0/ingestAutomation-upgrade/OAIBatch/PostgresDAO.py@8026
Revision 8026, 29.1 KB checked in by sdonegan, 8 years ago (diff)

Various updates to improve reporting and utf-8 handling - note requires ElementTree 1.3 or higher

Line 
1#!/usr/bin/env python
2'''
3Class representing the data access object wrapping the Postgres DB
4C Byrom Apr 08
5'''
6import sys, os, logging, datetime, re, codecs
7#from SpatioTemporalData import *
8from ndg.common.src.clients.reldb.postgres.postgresclient import PostgresClient as pgc
9
10
11class PostgresDAO:
12   
13    def __init__(self, record, isoDataModel,transformationDir, pgClient = None, dpwsID = None):
14        '''
15        Constructor - to initialise the DAL and do some initial setting up
16        @param record: the PostgresRecord object to add or update in the DB
17        @keyword pgClient: a postgresClient object to use to connect to postgres
18        - NB, if not set, will try to set one up by looking for a pg.config file
19        locally
20        '''
21        if record == "":
22            sys.exit("USAGE: argument 1 = PostgresRecord object to process")
23        else:
24            logging.info("INFO: Creating/updating DB entry for record, %s" %record.discovery_id)
25
26        # setup a connection to the db - if none specified
27        if pgClient is None:
28            self.pgc = pgc(configFile, pgc.DEFAULT_CONFIG_FILE)
29        else:
30            self.pgc = pgClient
31
32        self._record = record
33       
34        self.isoDataModel = isoDataModel       
35        self.discovery_dir = transformationDir
36        self.dpwsID = dpwsID
37       
38        self.processingWarning = ''
39       
40       
41       
42   
43
44    def getRecordID(self):
45        '''
46        Looks up a record in the DB and returns its DB ID, if it exists, otherwise
47        returns '-1'
48        @return: id of record, if it exists, '-1' if it doesn't
49        '''
50        logging.info("Looking up record, " + self._record.discovery_id + " in DB")
51        if self._record.db_id is not None and self._record.db_id > 0:
52            logging.info("Already looked up record - ID is " + str(self._record.db_id))
53            return self._record.db_id
54       
55        sql = "SELECT original_document_id FROM ORIGINAL_DOCUMENT where discovery_id = '" + \
56            self._record.discovery_id + "';"
57           
58        logging.info("sql lookup cmd = " + sql)
59        dbId = self.pgc.runSQLCommand(sql)
60        if dbId:
61            self._record.db_id = dbId[0][0]
62           
63           
64    def getRecordID_using_OriginalDocumentFilename(self):
65        '''
66        Looks up a record in the DB and returns its DB ID, if it exists, otherwise
67        returns '-1'
68        @return: id of record, if it exists, '-1' if it doesn't
69        '''
70        logging.info("Looking up original_document_id for filename: " + self._record.filename + " in DB")
71       
72        '''if self._record.db_id is not None and self._record.db_id > 0:
73            logging.info("Already looked up record - ID is " + str(self._record.db_id))
74            return self._record.db_id'''
75       
76        sql = "SELECT original_document_id FROM ORIGINAL_DOCUMENT where original_document_filename = '" + self._record.filename + "';"
77       
78        dbId = self.pgc.runSQLCommand(sql)
79       
80        if dbId:
81            self._record.db_id = dbId[0][0]
82           
83           
84    def getDiscoveryID_using_OriginalDocumentFilename(self):
85        '''
86        Looks up a record in the DB and returns its discovery ID, if it exists, otherwise
87        returns '-1'
88        @return: id of record, if it exists, '-1' if it doesn't
89        '''
90        logging.info("Looking up discovery_of for filename: " + self._record.filename + " in DB")
91       
92        '''if self._record.db_id is not None and self._record.db_id > 0:
93            logging.info("Already looked up record - ID is " + str(self._record.db_id))
94            return self._record.db_id'''
95       
96        sql = "SELECT discovery_id FROM ORIGINAL_DOCUMENT where original_document_filename = '" + self._record.filename + "';"
97       
98        dbId = self.pgc.runSQLCommand(sql)
99       
100        if dbId:
101            self._record.discovery_id = dbId[0][0]
102           
103       
104    def getTemporalDataId(self):
105       
106        '''
107        Looks up the temporal data id using the original document id
108        '''
109       
110        logging.info("Looking up temporal_data_id for filename: " + self._record.filename + " in DB")
111       
112        sql = "SELECT discovery_id FROM ORIGINAL_DOCUMENT where original_document_filename = '" + self._record.filename + "';"
113
114       
115       
116
117    def createOrUpdateRecord(self):
118        '''
119        Looks up a record in the DB; if it finds it, update it, otherwise create it
120        @return result: True if record created/updated, false if otherwise
121        '''
122       
123        self.getRecordID()
124        returnCode=None # 0 if failed, 1 if update, 2 if create       
125        msg = None
126       
127        try:
128            if self._record.db_id:               
129                if self.updateRecord():                 
130                       returnCode = 1
131            else:
132                #create the record!         
133                if self.createRecord():
134                       returnCode = 2
135                       
136        except Exception, error:
137           
138            returnCode = 0
139           
140            if (type(error).__name__ == 'UnicodeEncodeError') or (type(error).__name__ == 'UnicodeDecodeError'):
141                #get the position of the dodgy characters & message
142                convertMsg = 'Error with character encoding in this field (%s): %s'%(type(error).__name__,error)
143                logging.warn(convertMsg)
144                msg = convertMsg
145               
146            else:
147                logging.error("Error detected with parsing and inserting record into the database")
148                msg = "Possible error with sql content (bad characters?)"
149               
150        return returnCode, msg
151           
152
153           
154    def createRecord(self):
155        '''
156        Create a record in the postgres DB based on the specified PostgresRecord object
157        @return result: True if record created, false if otherwise
158        '''
159        logging.info("Creating a new record in the DB for the metada document")
160        # firstly store the actual documents contained by the record - i.e. the original doc +
161        # the various transforms required
162       
163        self._insertOriginalRecord()
164        self._insertMetadataRecords()
165       
166        # Now add the spatiotemporal data
167        self._insertSpatioTemporalData()
168       
169        #if iso original metadata format, add in additional fields       
170        self._updateISOcolumns()
171       
172        logging.info("New record created")
173        return True
174       
175       
176   
177    def _updateISOcolumns(self):
178        '''
179        Method to control the update of the extra ISO columns required for full MEDIN ingest
180        '''
181       
182        dbColumns = self.isoDataModel.mapIsoFieldsToDBcolumns()
183       
184        processingMessage = ''
185       
186        for isoData in dbColumns.keys():
187               
188                logging.info("Attempting to update: " + isoData)                               
189                                       
190                columnValue = getattr(self.isoDataModel,isoData)
191                columnName = dbColumns[isoData]
192               
193                if columnValue is not None:
194                        updateReport,updateMessage = self._updateDataBaseColumn(self._record.shortFilename, columnName, columnValue)
195                       
196                        if updateReport:
197                                logging.info("Successfully updated " + isoData)
198                               
199                                if updateMessage != '':
200                                        logging.info("Processing warning: %s" %updateMessage)
201                                        processingMessage = '[' + columnName +']: ' + updateMessage + "\n"
202                                       
203                        else:
204                                logging.warn("Could not update " + isoData)
205                else:
206                        logging.info(isoData + " is None - skipping")
207       
208        if processingMessage != '':
209                self.processingWarning = processingMessage
210               
211               
212               
213   
214    '''
215    Method to update individual columns within the Discovery database based on unique id (original_document_filename,
216    column name and value to be inserted into that column
217    '''
218    def _updateDataBaseColumn(self,original_document_filename,columnName,columnValue):
219       
220        report = False
221        reportMsg = ''
222       
223        logging.info("Updating " + columnName + " for record: " + original_document_filename)
224                               
225        #get the matching dictionary of postgres datatypes defined in the iso model
226        postgresDataType = self.isoDataModel.mapDBcolumnsToIsoDataTypes()[columnName]
227       
228        #construct the actual sql command here - easier to handle than using sql function (& to adapt!)
229        #remember doing it on a 1:1 basis here - convert raw multi list to space delimited value if text of tsVector
230        if (postgresDataType == 'tsvector') or (postgresDataType == 'text'):
231               
232                logging.info("Data type is text or tsvector!")
233                               
234                #need to work out whether value passed here to be updated is a string or list
235                if type(columnValue) is list:
236                       
237                        if len(columnValue[0]) == 0:
238                                logging.info("No data to extract - no point continuing!")
239                                return False,reportMsg
240                         
241                        elif len(columnValue[0]) > 1:
242                                newColVal = ""
243                                cnt = 0
244                               
245                                for val in columnValue[0]:
246                                        if cnt == 0:
247                                                newColVal = newColVal + val
248                                else:
249                                                newColVal = newColVal + "; " + val
250                               
251                                cnt = 1
252                         
253                        else:
254                                #test & get rid of any special characters - but flag it up for ingest report
255                                #newColVal = self._record.escapeSpecialCharacters(str(columnValue[0][0]))
256                               
257                                newColVal,reportMsg = self._record.characterEncoding(columnValue[0][0])
258                               
259                                newColVal = self._record.escapeSpecialCharacters(newColVal)
260                               
261                else:
262                        logging.info("Value type for %s has already been converted to a simple string" %columnName )
263         
264                        #remaining type to deal with is the value has already been converted to a simple string (i.e. authors, data centre name)
265                        #newColVal = self._record.escapeSpecialCharacters(columnValue)
266                        newColVal,reportMsg = self._record.characterEncoding(columnValue)                                               
267                        newColVal = self._record.escapeSpecialCharacters(newColVal)
268                       
269               
270               
271        elif postgresDataType == 'boolean':
272                logging.info("Data type is Boolean!")
273                newColVal = columnValue
274                       
275        else:
276                logging.info("Data type not text or vector!")
277               
278                if len(columnValue[0]) == 0:
279                        newColVal = "null"
280                elif len(columnValue[0]) > 1:
281                        logging.warn("NOTE: " + columnName + " is attempting to add multiple values - just take first for now!")
282                        newColVal = self._record.escapeSpecialCharacters(columnValue[0][0])
283                else:
284                        newColVal = self._record.escapeSpecialCharacters(columnValue[0][0])
285               
286                #TODO: at some stage add some checking of timestamps etc
287               
288       
289       
290        #build the sql query
291        #i.e. update original_document set original_format_version = 'dooby' where original_document_filename = 'dooby.ac.uk.shgfhf.xml'
292        if postgresDataType == 'tsvector':
293                sqlCmd = "update original_document set " + columnName + " = to_tsvector('english','" + newColVal + "') where original_document_filename = '" + original_document_filename + "';"
294       
295        elif postgresDataType == 'boolean':
296                sqlCmd = "update original_document set  %s = %s where original_document_filename = '%s';" %(columnName,newColVal,original_document_filename)
297               
298        else:
299                sqlCmd = "update original_document set " + columnName + " = '" + newColVal + "' where original_document_filename = '" + original_document_filename + "';"
300       
301        #submit the sqlQuery
302        try:
303               
304                #deal with nones
305                sqlCmd = sqlCmd.replace("'null'", "null")
306                sqlCmd = sqlCmd.replace("'None'", "null")
307                sqlCmd = sqlCmd.replace("None", "null")
308               
309                #sort out escape chars from previous catches (i.e. parameters)
310                #sqlCmd = sqlCmd.replace("\\'","\'")           
311                               
312                self.pgc.runSQLCommand(sqlCmd)
313               
314                report = True
315               
316        except:
317                logging.error("Could not submit query for: " + sqlCmd)
318               
319       
320        return report,reportMsg
321       
322       
323
324    def updateRecord(self):
325        '''
326        Update a record in the postgres DB based on the specified PostgresRecord object
327        @return result: True if record updated, false if otherwise
328        '''
329        logging.info("Record already existing in DB - performing updates")
330        result = False
331       
332        # firstly, check the document is actually new - i.e. not just a repeat of the same data
333        if self._checkIsUpdatedRecord():
334           
335            # firstly, update the original record
336            self._updateOriginalRecord()
337           
338            # now update the actual documents contained by the record - i.e. the original doc +
339            # the various transforms required
340            self._updateMetadataRecords()
341           
342            # If doing an update of an existing record, clear out existing spatiotemporal
343            # data, rather than updating it, to keep things simple
344            logging.info("Clearing out existing data for record - to allow clean update")
345            self._deleteSpatioTemporalData()
346            self._insertSpatioTemporalData()
347            result = True
348           
349            #if iso original metadata format, add in additional fields
350            self._updateISOcolumns()
351       
352        logging.info("Finish processing document...")
353       
354        return result
355       
356       
357       
358    def _checkIsUpdatedRecord(self):
359        '''
360        Looks up an existing record and checks it is not identical to the new record; if it is
361        incremement the harvest_count value and don't process again
362        @return: True if doc contains changes, False otherwise
363        '''
364        logging.info("Checking the updated document actually contains changes")
365       
366        #sql = "SELECT harvest_count, scn FROM ORIGINAL_DOCUMENT where original_document_id = " + \
367        #    str(self._record.db_id) + " AND original_document = '" + self._record.originalFormat + "';"
368       
369        #get the harvest count and scn from the original_document table...
370        sql_orig = "SELECT harvest_count, scn FROM ORIGINAL_DOCUMENT where original_document_id = " + str(self._record.db_id) + ";"
371       
372        results_orig = self.pgc.runSQLCommand(sql_orig)
373       
374        #we MUST make sure we compare the original format - any xquery conversions will produce differences even if like for like
375        if self._record.docType == 'DIF_9.4':
376               
377                #make sure we escape any special characters....
378                origXMLToCompare = self._record.escapeSpecialCharacters(self._record.difXML)
379        else:           
380                origXMLToCompare = self._record.escapeSpecialCharacters(self._record.isoXML)
381       
382        #get the original_document from the transformed docs table       
383        sql_transf = "SELECT transformed_document_id FROM transformed_document where original_document_id = " + str(self._record.db_id) +  \
384                " AND transformed_document = '" + origXMLToCompare + "';"
385       
386        #import pdb
387        #pdb.set_trace()
388        results_transf = self.pgc.runSQLCommand(sql_transf)       
389       
390        # NB, if the document is not identical, the sql command will not find anything
391        if not results_transf:
392            logging.info("Ingested document is different to that in the current DB")
393           
394            # get the current SCN
395            sql = "SELECT scn FROM ORIGINAL_DOCUMENT where original_document_id = " + \
396                    str(self._record.db_id) + ";"
397            results = self.pgc.runSQLCommand(sql)
398            self._record.scn = results[0][0]
399            return True
400           
401        count = results_orig[0][0]
402
403        # get current system change number
404        scn = results_orig[0][1]
405        self._record.scn = scn
406        logging.info("Ingested document is identical to document currently in DB - " + \
407                     "incrementing harvest_count")
408        count += 1
409        sql = "UPDATE ORIGINAL_DOCUMENT SET harvest_count = " + str(count) + \
410            " WHERE original_document_id = " + str(self._record.db_id)
411        self.pgc.runSQLCommand(sql)
412        return False
413
414
415    def _deleteSpatioTemporalData(self):
416        '''
417        Delete all existing spatiotemporal data for the current record
418        - NB, the delete is set to cascade from the linking table so only need to
419        delete entries from there
420        '''
421        logging.info("Deleting existing spatial data for record")
422       
423        try:
424                sqlCmd = "DELETE FROM spatial_data WHERE original_document_id = " + str(self._record.db_id) + ";"
425               
426                self.pgc.runSQLCommand(sqlCmd)
427               
428                logging.info("Spatial data for %s deleted ok" %self._record.db_id)
429           
430        except:
431                logging.error("Could not delete spatial record %s" %self._record.db_id)
432       
433       
434        logging.info("Deleting existing temporal data for record")
435       
436        try:
437                sqlCmd = "DELETE FROM temporal_data WHERE original_document_id = " + str(self._record.db_id) + ";"
438               
439                self.pgc.runSQLCommand(sqlCmd)
440               
441                logging.info("temporal data for %s deleted ok" %self._record.db_id)
442           
443        except:
444                logging.error("Could not delete temporal record %s" %self._record.db_id)
445       
446        logging.info("Spatio - temporal data deleted successfully")
447       
448
449
450    def _insertSpatioTemporalRow(self, coords, timeRange):
451        '''
452        Create a single row record in the postgres DB based on the
453        input data.  Updated to operate with dictionary methods for coords and timeRange as part of MEDIN ISO upgrade
454        @param coords: a Coords object representing NSWE coords
455        @param timeRange: a TimeRange object representing a start/end date
456        '''
457        logging.info("Adding spatiotemporal row to DB")
458       
459       
460        sqlCmd = "SELECT add_spatiotemporal_row('" + str(self._record.db_id) + "', '" + \
461            str(coords['north']) + "', '" + str(coords['south']) + "', '" + str(coords['west']) + "', '" + \
462            str(coords['east']) + "', '" + timeRange['start'] + "', '" + timeRange['end'] + "');"
463           
464        # fix any null strings
465        sqlCmd = sqlCmd.replace("'null'", "null")
466               
467        self.pgc.runSQLCommand(sqlCmd)
468        logging.info("Spatiotemporal row added successfully")
469       
470       
471   
472    def _insertSpatioTemporalData(self):
473        '''
474        Create a record in the postgres DB based on the spatiotemporal data
475        specified in the PostgresRecord object
476       
477        Note updated to work with ISO metadata object where coords and times already defined as individual items.
478       
479        '''
480        logging.info("Adding spatiotemporal data to DB record")
481       
482        # Work out the relationship between the spatial and temporal data and handle appropriately
483       
484       
485        TimeRange = self._record.parseTemporalInfo(self._record.datasetTemporalData)
486        SpatialCoords = self._record.parseSpatialInfo(self._record.datasetSpatialData)
487       
488       
489        if (len(TimeRange) == 0) and (len(SpatialCoords) == 0):
490                logging.info("No spatiotemporal data found for record - skipping")
491                return
492       
493       
494        # if both arrays of data are the same length, assume they map together       
495        i = 0
496        if len(TimeRange) == len(SpatialCoords):
497            logging.info("Spatial data is the same size as temporal data; assuming these map together one to one")
498            for times in TimeRange:
499                self._insertSpatioTemporalRow(SpatialCoords[i], times)
500                i += 1
501
502        # otherwise, map everything to everything
503        else:
504            logging.info("Spatial and temporal data are of different sizes; map everything to everything")
505            for times in TimeRange:
506                for coords in SpatialCoords:
507                   
508                    self._insertSpatioTemporalRow(coords, times)
509                   
510        logging.info("Spatiotemporal data added to DB record")
511       
512       
513   
514    def _insertOriginalRecord(self):
515        '''
516        Insert the original metadata doc into the postgres DB
517        '''
518        logging.info("Inserting new original document in Postgres DB")
519       
520       
521        ''' ndg3 style command
522        sqlCmd = "SELECT create_document('" + self._record.shortFilename + "', '" + \
523            self._record.discovery_id + "', '" + self._record.docType + "', '" + \
524            self._record.originalFormat + "', '" + self._record.getAuthorsInfo() + "', '" + \
525            self._record.getParametersInfo() + "', '" + self._record.getScopeInfo() + "', '" + \
526            self._record.dataset_name + "', '" + self._record.datacentre_name + "', '" + self._record.dataset_lastEdit + "', '" + self._record.datasetStartNom + "', '" + self._record.datasetEndNom + "');"
527                   
528        '''
529       
530        #Get rid of any xml comment characters - causing problems
531        originalXMLdoc = re.sub("<!--.*-->","",self._record.originalFormat)
532       
533        #create the sql command
534       
535        #list of arguements in SEQUENCE order to be used with create_document SQL DB method.
536        args=[self._record.shortFilename,self._record.discovery_id,self.dpwsID,self._record.docType,originalXMLdoc,self._record.getAuthorsInfo(),self._record.escapeSpecialCharacters(self._record.getParametersInfo()),self._record.getScopeInfo(),self._record.dataset_name,self._record.datacentre_name,self._record.dataset_lastEdit,self._record.datasetStartNom,self._record.datasetEndNom]
537       
538        cmdStr = ''
539        cntr = 0
540        for vals in args:
541           
542            #unicode now enforced when pulling data from the xml.. but escap
543            #chckedVals,msg = self._record.characterEncoding(vals)
544            chckedVals = vals ; msg = ''
545           
546            if msg != '':           
547                logging.error(msg)
548                       
549            if cntr != 0:
550                cmdStr += ",'%s'" %chckedVals                   
551            else:
552                cmdStr += "'%s'" %chckedVals
553           
554            cntr += 1
555           
556               
557        #encapsulate within the correct structure..
558        sqlCmd = "SELECT create_document(%s)" % cmdStr
559        #import pdb ; pdb.set_trace()
560       
561       
562        #sqlCmd = "SELECT create_document('" + self._record.shortFilename + "', '" + \
563        #    self._record.discovery_id + "', '" + self.dpwsID + "', '" + self._record.docType + "', '" + \
564         #   originalXMLdoc + "', '" + self._record.getAuthorsInfo() + "', '" + \
565        #    self._record.escapeSpecialCharacters(self._record.getParametersInfo()) + "', '" + self._record.getScopeInfo() + "', '" + \
566         #   self._record.escapeSpecialCharacters(self._record.dataset_name) + "', '" + self._record.datacentre_name + "', '" + \
567        #    self._record.dataset_lastEdit + "', '" + self._record.datasetStartNom + "', '" + self._record.datasetEndNom + "' );"
568       
569        #sort out any nulls..
570        sqlCmd = sqlCmd.replace("'NULL'","NULL")
571        sqlCmd = sqlCmd.replace("'null'","null")
572       
573        #sort out any Nones
574        sqlCmd = sqlCmd.replace("'None'","NULL")
575       
576       
577        id = self.pgc.runSQLCommand(sqlCmd)
578        if len(id) == 0:
579            raise ValueError, 'No PK ID returned from INSERT to DB'
580       
581        self._record.db_id = id[0][0] 
582       
583        logging.info("Original document inserted in Postgres DB")
584           
585   
586    def deleteOriginalRecord(self):
587        '''
588        Delete the original metadata doc from the postgres DB
589        '''
590        logging.info("Deleting original document from Postgres DB")
591        sqlCmd = "SELECT delete_document('" + str(self._record.db_id) + "');" 
592
593        self.pgc.runSQLCommand(sqlCmd)
594        logging.info("Original document deleted from Postgres DB")
595       
596   
597    def _updateOriginalRecord(self):
598        '''
599        Update the original doc in the postgres DB
600        '''
601       
602        logging.info("Updating original document in Postgres DB")
603        #sqlCmd = "SELECT update_document('" + str(self._record.db_id) + "', '" + \
604        #    self._record.shortFilename + "', '" + self.dpwsID + "', '" +\
605        #    self._record.discovery_id + "', '" + self._record.docType + "', '" + \
606         #   self._record.originalFormat + "', '" + self._record.getAuthorsInfo() + "', '" + \
607         #   self._record.escapeSpecialCharacters(self._record.getParametersInfo()) + "', '" + self._record.getScopeInfo() + "', '" + \
608         #   str(self._record.scn) + "', '" + self._record.dataset_name + "', '" + self._record.datacentre_name + \
609         #   "', '" + self._record.dataset_lastEdit + "', '" + self._record.datasetStartNom + "', '" + \
610          #  self._record.datasetEndNom + "');"
611           
612       
613        args=[str(self._record.db_id), self._record.shortFilename,self.dpwsID,self._record.discovery_id,self._record.docType,self._record.originalFormat,self._record.getAuthorsInfo(),self._record.escapeSpecialCharacters(self._record.getParametersInfo()),self._record.getScopeInfo(),str(self._record.scn),self._record.dataset_name,self._record.datacentre_name,self._record.dataset_lastEdit,self._record.datasetStartNom,self._record.datasetEndNom]
614       
615        cmdStr = ''
616        cntr = 0
617        for vals in args:
618           
619            #unicode now enforced when pulling data from the xml.. but escap
620            #chckedVals,msg = self._record.characterEncoding(vals)
621            chckedVals = vals ; msg = ''
622           
623            if msg != '':           
624                logging.error(msg)
625                       
626            if cntr != 0:
627                cmdStr += ",'%s'" %chckedVals                   
628            else:
629                cmdStr += "'%s'" %chckedVals
630           
631            cntr += 1
632           
633               
634        #encapsulate within the correct structure..
635        sqlCmd = "SELECT update_document(%s);" % cmdStr
636       
637       
638        #sort out any NULL values"
639        sqlCmd = sqlCmd.replace("'NULL'","NULL")
640       
641        #sort out any Nones
642        sqlCmd = sqlCmd.replace("'None'","NULL")       
643       
644        logging.info("Submitting SQL command")
645        #logging.info("SQl command:   " + sqlCmd)         
646       
647        self.pgc.runSQLCommand(sqlCmd)
648       
649        # increment scn - saves doing an additional db call
650        self._record.scn += 1
651       
652        logging.info("Original document updated in Postgres DB")
653   
654           
655    def _insertMetadataRecords(self):
656        '''
657        Insert the metadata docs into the postgres DB
658        '''
659        logging.info("Inserting transformed documents for original document, %s, in Postgres DB", self._record.shortFilename)
660       
661       
662        if self._record.db_id is None:
663            logging.info("No DB ID for the original record exists; cannot add associated transformed docs")
664            return
665       
666        #for docType, doc in self._record.getAllDocs(self.discovery_dir):       
667        metadataDocs = self._record.getAllDocs(self.discovery_dir)       
668                       
669        for docType in metadataDocs.keys():
670                               
671            logging.info("Inserting metadata of type %s" %docType)
672           
673            #fudge!
674            if docType == 'DIF_9.4':
675                               
676                #don't need to escape special characters again -as dealt with when getAllDocs was called..
677                #doc = self._record.escapeSpecialCharacters(str(metadataDocs[docType]))
678                doc = metadataDocs[docType]
679               
680               
681            else:
682                doc = str(metadataDocs[docType])
683                                               
684            sqlCmd = "INSERT INTO TRANSFORMED_DOCUMENT (transformed_document_id, " \
685                "original_document_id, transformed_format, " \
686                "transformed_document, create_date, scn) VALUES (" \
687                "DEFAULT, '" + str(self._record.db_id) + "', '" + \
688                docType + "', '" + doc + "', current_timestamp, 1);"
689               
690           
691            #print "\n\n\n%s\n\n\n" %sqlCmd
692           
693            self.pgc.runSQLCommand(sqlCmd)
694       
695        logging.info("Transformed records created in DB")
696   
697   
698    def _updateMetadataRecords(self):
699        '''
700        Update the metadata docs into the postgres DB
701        '''
702       
703        logging.info("Updating transformed documents for original document, %s, in Postgres DB", self._record.shortFilename)
704        if self._record.db_id is None:
705            logging.info("No DB ID for the original record exists; cannot update associated transformed docs")
706            return
707       
708        #for docType, doc in self._record.getAllDocs(self.discovery_dir):
709        metadataDocs = self._record.getAllDocs(self.discovery_dir)
710               
711        for docType in metadataDocs.keys():
712               
713                logging.info("Updating metadata of type %s" %docType)
714               
715                sqlCmd = "UPDATE TRANSFORMED_DOCUMENT SET transformed_document = '" +  self._record.escapeSpecialCharacters(metadataDocs[docType]) + "', update_date = current_timestamp WHERE original_document_id = " + str(self._record.db_id) + " AND transformed_format = '" + docType + "';"
716               
717                self.pgc.runSQLCommand(sqlCmd)
718   
719        logging.info("Transformed records updated in DB")
720
721
722    def setRecord(self, record):
723        '''
724        Set the record to use with the DAL - to allow object re-use
725        @param record: PostgresRecord to use with the DAL
726        '''
727        self._record = record
728
Note: See TracBrowser for help on using the repository browser.