Changeset 8545 for mauRepo


Ignore:
Timestamp:
30/08/12 08:40:42 (7 years ago)
Author:
mnagni
Message:

Complete - # 22528: Migration of FAtCat Open Search link for HPFeld
 http://team.ceda.ac.uk/trac/ceda/ticket/22528
Adds a ceda_timestamp column to the tm_instant table to simplify the search-by-time in cedamoles.
The code has been changed consequently to use the new parameter.

Location:
mauRepo/MolesManager/trunk/cedaMoles
Files:
3 added
9 edited

Legend:

Unmodified
Added
Removed
  • mauRepo/MolesManager/trunk/cedaMoles/MolesManager/db/after_flush.py

    r8514 r8545  
    3131@author: mnagni 
    3232''' 
    33 from cedaMoles.MolesManager.db.partyIndexes import addPartyIndexes, deletePartyIndexes,\ 
     33from cedaMoles.MolesManager.db.partyIndexes import addPartyIndexes, \ 
    3434    updatePartyIndexes 
    3535from ea_model.moles3_4.utilities.mo_responsiblepartyinfo import MO_ResponsiblePartyInfo 
    36 def afterFlush(session, flush_context): 
     36def after_flush(session, flush_context): 
    3737    # created a new one?         
    3838    for instance in session.new: 
     
    4343    for instance in session.dirty: 
    4444        if isinstance(instance, MO_ResponsiblePartyInfo): 
    45             updatePartyIndexes(instance, session) 
     45            updatePartyIndexes(instance, session)            
    4646                 
    4747    # deleted an existing one             
  • mauRepo/MolesManager/trunk/cedaMoles/MolesManager/db/partyIndexes.py

    r8514 r8545  
    5454        self.party_order = None 
    5555 
    56 def associateMOParty_indexes(metadata): 
     56def associate_moparty_indexes(metadata): 
    5757    ''' 
    5858    Creates the table used to store the index associated per ResponsiblePartyIngo  
  • mauRepo/MolesManager/trunk/cedaMoles/MolesManager/moles3epb.py

    r8538 r8545  
    3232''' 
    3333from cedaMoles.libs.epb import EPB 
     34from cedaMoles.MolesManager.db.tm_instant import customize_tm_instant 
     35from cedaMoles.MolesManager.db.search_indexes import init_search_indexes 
     36from cedaMoles.MolesManager.db.ceda_guid import init_ceda_guid 
     37from cedaMoles.MolesManager.db.after_flush import after_flush 
    3438from ea_model.moles3_4.observationcollection.mo_observationcollection \ 
    3539    import MO_ObservationCollection 
    3640from ea_model.moles3_4.observation.mo_observation import MO_Observation 
    37 from sqlalchemy import Table, Column, ForeignKey, Integer, String, event 
    38 from sqlalchemy.orm import mapper 
     41from sqlalchemy import event 
    3942from cedaMoles.MolesManager.ceda_guid import CedaGUID 
    4043from sqlalchemy.orm.collections import InstrumentedList 
     
    5255from ea_model.ceda_metadatamodel.ceda_project.ceda_project import CEDA_Project 
    5356from cedaMoles.MolesManager.codelist import MM_RoleValue, getCLValue 
    54 from cedaMoles.libs.migration.processor.commons import from_pt_to_string 
    55 from datetime import datetime 
    5657from ascore.utils import synchAttributes 
    57 from cedaMoles.MolesManager.db.partyIndexes import associateMOParty_indexes 
    58 from cedaMoles.MolesManager.db.after_flush import afterFlush 
     58from cedaMoles.MolesManager.db.partyIndexes import associate_moparty_indexes 
    5959 
    6060class Moles3EPBFactory(EPB):    
     
    6464 
    6565    def _init_ceda_customization(self): 
    66         self._associate_ceda_guid() 
    67         associateMOParty_indexes(self._db_manager.metadata) 
    68         self._initSearchIndexes()   
    69          
    70     def _associate_ceda_guid(self): 
    71         guid_table = Table('ceda_guid', self._db_manager.metadata,  
    72                            Column('id', String, primary_key=True),  
    73                            Column('ceda_observationcollection',  
    74                                   Integer, ForeignKey('ceda_observationcollection.id')),  
    75                            Column('ceda_observation',  
    76                                   Integer, ForeignKey('ceda_observation.id')), 
    77                            Column('ceda_project',  
    78                                   Integer, ForeignKey('ceda_project.id'))) 
    79         mapper(CedaGUID, guid_table) 
    80         self._db_manager.metadata.create_all() 
    81  
    82     def _initSearchIndexes(self): 
    83         #To Be Done - CHECK IF THE COLUMN ALREADY EXISTS! 
    84         # We don't want sqlalchemy to know about this column so we add it externally. 
    85         try: 
    86             self._db_manager.engine.execute("alter table md_identifier \ 
    87                 add column code_search_vector tsvector")                  
    88  
    89             # This indexes the tsvector column 
    90  
    91             self._db_manager.engine.execute("create index \ 
    92                 md_identifier_code_search_index on md_identifier using gin(code_search_vector)") 
    93  
    94             # This sets up the trigger that keeps the tsvector column up to date. 
    95             self._db_manager.engine.execute("create trigger \ 
    96                 md_identifier_code_search_update \ 
    97                 before update or insert on md_identifier \ 
    98                 for each row execute procedure \ 
    99                 tsvector_update_trigger('code_search_vector', \ 
    100                                         'pg_catalog.english', code)")                         
    101         except Exception: 
    102             pass 
     66        init_ceda_guid(self._db_manager.metadata)         
     67        associate_moparty_indexes(self._db_manager.metadata) 
     68        init_search_indexes(self._db_manager.engine) 
     69        customize_tm_instant(self._db_manager.engine, self._db_manager.metadata) 
    10370         
    10471    def createEPB(self): 
    10572        session = self._get_session() 
    106         event.listen(session, 'after_flush', afterFlush) 
     73        event.listen(session, 'after_flush', after_flush)       
    10774        return Moles3EPB(session) 
    10875 
     
    137104             
    138105        **Returns** 
    139             An updated, session independent, object instance reflecting the new persisted object  
     106            An updated, session independent, object instance reflecting  
     107            the new persisted object  
    140108        """ 
    141109        EPB.persistInstance(instance, self._session)         
     
    225193            @param collection: an CEDA_ObservationColleciton instance   
    226194        """ 
     195        if not hasattr(collection, 'member'): 
     196            return None 
     197         
    227198        bboxes = [] 
    228         if not hasattr(collection, 'member'): 
    229             return bboxes 
    230199        for member in collection.member: 
    231200            for ge in member.geographicExtent: 
     
    428397    """ 
    429398    return "%s-%s-%s" % (dt.year, dt.month, dt.day) 
    430  
    431 def unify_observation_collection_phenomenon_time(collection): 
    432     """ 
    433         Returns the time period of the collections.member'a  phenomenonTime(s) 
    434         @param collection: an CEDA_ObservationColleciton instance  
    435         @return: a tuple (startDate, endDate) strings 
    436     """ 
    437     dateFormat = '%Y-%m-%d' 
    438     ptStart = [] 
    439     ptEnd = []       
    440     for member in collection.member: 
    441         if member.phenomenonTime is None: 
    442             continue 
    443              
    444         pt =  member.phenomenonTime 
    445         ptString = from_pt_to_string(pt) 
    446         if ptString[0] is not None:                     
    447             ptStart.append(datetime.strptime(ptString[0], dateFormat)) 
    448         if ptString[1] is not None:                     
    449             ptEnd.append(datetime.strptime(ptString[1], dateFormat)) 
    450     ptStart.sort()                     
    451     ptEnd.sort() 
    452     start = None 
    453     end = None 
    454     #takes the earlier date 
    455     if len(ptStart) > 0: 
    456         start = _tmpstrftime(ptStart[0])  
    457     #takes the latest date 
    458     if len(ptEnd) > 0: 
    459         end = _tmpstrftime(ptEnd[len(ptEnd) - 1])  
    460     return start, end  
  • mauRepo/MolesManager/trunk/cedaMoles/MolesManager/views/moles2gui/__init__.py

    r8537 r8545  
    1111from cedaMoles.libs.epb import isPrimitive 
    1212 
    13 """ 
     13''' 
    1414    From now on we define: 
    1515    - cedaObject any instances or class defined in from the CedaMoles3 model 
    16     - jsonObject any json representation generated by the CedaMolesGuiAdapter.encode method 
    17 """ 
    18  
    19 _encodeMapper = {'ea_model.iso_19115_2006_metadata_corrigendum.\ 
     16    - jsonObject any json representation generated  
     17            by the CedaMolesGuiAdapter.encode method 
     18''' 
     19 
     20_ENCODE_MAPPER = {'ea_model.iso_19115_2006_metadata_corrigendum.\ 
    2021extent_information.ex_geographicboundingbox.EX_GeographicBoundingBox': 
    2122                    ('cedaMoles.MolesManager.views.moles2gui.ex.geographic_extent',  
     
    333334    # Is a mapped class? 
    334335    key = "%s.%s" % (cedaObj.__module__, cedaObj.__class__.__name__) 
    335     if _encodeMapper.has_key(key):    
    336         module, clazz = _encodeMapper[key] 
     336    if _ENCODE_MAPPER.has_key(key):    
     337        module, clazz = _ENCODE_MAPPER[key] 
    337338        encoder = dynamicallyLoadClass(module, clazz) 
    338339        return encoder.cedaObjToAdapter(cedaObj) 
  • mauRepo/MolesManager/trunk/cedaMoles/libs/migration/MigrationEPB.py

    r8538 r8545  
    3030        """ 
    3131            Adds a new migration object. 
    32             @param migrationObj: the migration object to add 
    33             @param session: an SQLAlchemy Session object. If None (default) the method creates 
    34             @return an updated, session independent, object instance reflecting the new persisted object  
    35         """       
     32             
     33            **Parameters** 
     34                * instance: the instance to persist 
     35             
     36            **Raise** 
     37                * Exception both `moles3EPB` and `cedaMoleObj` are `None` 
     38        """           
    3639        EPB.persistInstance(instance, self._session) 
    3740 
    38     def getAllDeploymentsMigrationByDataEntitySortedByDate(self, dataEntity, deploymentNames): 
    39         return EPB.getAllObjects(DeploymentsMigration, self._session).filter(DeploymentsMigration.doc_name.in_(deploymentNames)).order_by(asc("doc_creation")).all() 
     41    def getAllDeploymentsMigrationByDataEntitySortedByDate(self, dataEntity,  
     42                                                           deploymentNames): 
     43        return EPB.getAllObjects(DeploymentsMigration, self._session).\ 
     44            filter(DeploymentsMigration.doc_name.in_(deploymentNames)).\ 
     45            order_by(asc("doc_creation")).all() 
    4046 
    4147    def _getMigrationObject(self, mo_type, doc_status, doc_owner, doc_name): 
    42         return self._session.query(mo_type).filter(*[EPB.buildFilter('doc_name', doc_name)]).first() 
     48        return self._session.query(mo_type).\ 
     49            filter(*[EPB.buildFilter('doc_name', doc_name)]).first() 
    4350 
    4451    def _getMigrationObjectByName(self, mo_type, migration_object, doc_name): 
    45         return self._getMigrationObject(mo_type, migration_object.doc_status, migration_object.doc_owner, doc_name)              
     52        return self._getMigrationObject(mo_type, migration_object.doc_status,  
     53                                        migration_object.doc_owner, doc_name)              
    4654 
    4755    def get_deployment_data_migration_by_name(self, migration_object, doc_name): 
    4856        if migration_object is None: 
    4957            raise Exception("migrationObject is None") 
    50         return self._getMigrationObjectByName(DeploymentDataMigration, migration_object, doc_name) 
     58        return self._getMigrationObjectByName(DeploymentDataMigration,  
     59                                              migration_object, doc_name) 
    5160 
    5261    def getDataEntityMigrationbyPath(self, migration_object): 
     
    5766        ret = [] 
    5867        if migration_object: 
    59             ret.append(self._session.query(DataEntityMigration).filter(*[EPB.buildFilter('doc_name', migration_object.doc_name)]).first())                
     68            ret.append(self._session.query(DataEntityMigration).\ 
     69                       filter(*[EPB.buildFilter('doc_name', migration_object.doc_name)]).\ 
     70                       first())                
    6071        else: #then process all the DataEntities 
    6172            res = self._session.query(DataEntityMigration).all() 
  • mauRepo/MolesManager/trunk/cedaMoles/libs/migration/processor/commons.py

    r8522 r8545  
    625625    tm_instant = TM_Instant() 
    626626    tm_instant.position = position 
     627    if hasattr(tm_instant, 'ceda_timestamp'): 
     628        if isinstance(position.date8601, Date): 
     629            idate = position.date8601 
     630            tm_instant.ceda_timestamp = datetime.datetime(int(idate.year),  
     631                                                     int(idate.month),  
     632                                                     int(idate.day)) 
     633        elif isinstance(position.dateTime8601, DateTime): 
     634            idate = position.dateTime8601 
     635            tm_instant.ceda_timestamp = datetime.datetime(int(idate.year),  
     636                                                     int(idate.month),  
     637                                                     int(idate.day), 
     638                                                     int(idate.hour), 
     639                                                     int(idate.minute), 
     640                                                     int(idate.second)) 
    627641    return tm_instant 
    628642 
     
    955969    return ceda_project 
    956970 
    957 def from_date_string_to_pt(doc_phenomenon_time): 
     971def from_date_string_to_pt(start, end): 
    958972    """ 
    959973        Transforms a date string like '2002-07-22' (startDate) in a TM_Instant instance or    
     
    961975        @param doc_phenomenon_time: a date string in the expected format 
    962976    """ 
    963     if doc_phenomenon_time: 
    964         pt = None 
    965         if '/' in doc_phenomenon_time: 
    966             period = doc_phenomenon_time.split('/') 
    967             begin_date = create_date(isoDateStringToTimeDate(period[0])) 
    968             begin_position = create_tm_position(date8601 = begin_date) 
    969             begin_tm_instant = create_tm_instant(begin_position) 
    970              
    971             end_date = create_date(isoDateStringToTimeDate(period[1])) 
    972             end_position = create_tm_position(date8601 = end_date) 
    973             end_tm_instant = create_tm_instant(end_position) 
    974              
    975             pt = create_tm_period(begin_tm_instant, end_tm_instant) 
    976         else: 
    977             tm_position = create_tm_position(date8601 = \ 
    978                                             create_date(isoDateStringToTimeDate(doc_phenomenon_time))) 
    979             pt = create_tm_instant(tm_position) 
    980         return pt 
    981  
     977    pt = None 
     978    if end is not None and start is not None: 
     979        begin_date = start 
     980        if isinstance(start, str): 
     981            begin_date = isoDateStringToTimeDate(start) 
     982        begin_position = create_tm_position(date8601 = create_date(begin_date)) 
     983        begin_tm_instant = create_tm_instant(begin_position) 
     984         
     985        end_date = end 
     986        if isinstance(end, str): 
     987            end_date = isoDateStringToTimeDate(end) 
     988        end_position = create_tm_position(date8601 = create_date(end_date)) 
     989        end_tm_instant = create_tm_instant(end_position)         
     990        pt = create_tm_period(begin_tm_instant, end_tm_instant) 
     991    elif start is not None: 
     992        begin_date = start 
     993        if isinstance(start, str): 
     994            begin_date = isoDateStringToTimeDate(start) 
     995        tm_position = create_tm_position(date8601 = create_date(begin_date)) 
     996        pt = create_tm_instant(tm_position) 
     997    return pt 
     998 
     999def unify_observation_collection_phenomenon_time(collection): 
     1000    """ 
     1001        Returns the time period of the collections.member'a  phenomenonTime(s) 
     1002        @param collection: an CEDA_ObservationColleciton instance  
     1003        @return: a tuple (startDate, endDate) strings 
     1004    """ 
     1005    ptStart = [] 
     1006    ptEnd = []       
     1007    for member in collection.member: 
     1008        if member.phenomenonTime is None: 
     1009            continue             
     1010        pt =  member.phenomenonTime 
     1011        if hasattr(pt, 'start'): 
     1012            ptStart.append(pt.start.ceda_timestamp) 
     1013        elif hasattr(pt, 'end'): 
     1014            ptEnd.append(pt.end.ceda_timestamp)             
     1015        elif hasattr(pt, 'ceda_timestamp'): 
     1016            ptStart.append(pt.ceda_timestamp)             
     1017    start = None 
     1018    end = None 
     1019    if len(ptStart) > 0: 
     1020        start = min(ptStart) 
     1021    #takes the latest date 
     1022    if len(ptEnd) > 0: 
     1023        end = max(ptEnd)                 
     1024    return start, end  
     1025 
     1026''' 
    9821027def from_pt_to_string(phenomenonTime): 
    9831028    """ 
     
    9981043        endDate = _tm_InstantToString(phenomenonTime.end) 
    9991044    return startDate, endDate 
    1000  
     1045''' 
    10011046def compare_phenomenon_times(p1, p2): 
    1002     s1 = from_pt_to_string(p1) 
    1003     s2 = from_pt_to_string(p2) 
    1004     return s1[0] == s2[0] and s1[1] == s2[1]  
    1005  
     1047    if hasattr(p1, 'start') and hasattr(p1, 'end') \ 
     1048        and hasattr(p2, 'start') and hasattr(p2, 'end'): 
     1049        return (p1.start.ceda_timestamp == p2.start.ceda_timestamp) \ 
     1050            and (p1.end.ceda_timestamp == p2.end.ceda_timestamp) 
     1051             
     1052    if hasattr(p1, 'ceda_timestamp') and hasattr(p2, 'ceda_timestamp'): 
     1053        return p1.ceda_timestamp == p2.ceda_timestamp 
     1054 
     1055    return False 
     1056 
     1057''' 
    10061058def _tm_InstantToString(tm_instant): 
    10071059    idate = tm_instant.position.date8601 
    10081060    return str(datetime.date(int(idate.year), int(idate.month), int(idate.day))) 
     1061''' 
    10091062 
    10101063def _from_geographic_bb_to_string(gbb): 
  • mauRepo/MolesManager/trunk/cedaMoles/libs/migration/processor/dataEntity.py

    r8537 r8545  
    4141    has_mo_been_processed, get_atom_document_hash_by_mo, extract_title, extract_summary, \ 
    4242    create_ex_geographic_boundingbox, from_date_string_to_pt, \ 
    43     compare_phenomenon_times, compareGeographicBoundingBoxes 
     43    compare_phenomenon_times, compareGeographicBoundingBoxes,\ 
     44    unify_observation_collection_phenomenon_time 
    4445from cedaMoles.libs.migration.processor.deployment import DeploymentProcessor 
    4546from logging import StreamHandler 
     
    5253from ea_model.ceda_metadatamodel.ceda_observationcollection.ceda_observationcollection \ 
    5354    import CEDA_ObservationCollection  
    54 from cedaMoles.MolesManager.moles3epb import unify_observation_collection_phenomenon_time 
    5555CEDA_TITLE = 'ceda_title' 
    5656 
     
    7878 
    7979    def _assignGeographicExtent(self, ceda_observationCollection): 
    80         bbox = self.epbRepo.moles3EPB.getUnifyObservationCollectionGEAsBBox(ceda_observationCollection) 
    81         if bbox is not None: 
    82             upperCornerData, lowerCornerData = bbox[4:len(bbox)-1].split(',') 
    83             east, north = upperCornerData.split() 
    84             west, south = lowerCornerData.split() 
    85             geographicExtent = create_ex_geographic_boundingbox(float(east), \ 
    86                                                                 float(north), \ 
    87                                                                 float(west), \ 
    88                                                                 float(south)) 
    89              
    90             if len(ceda_observationCollection.geographicExtent) == 0 or \ 
    91                 (len(ceda_observationCollection.geographicExtent) > 0 and \ 
    92                     not compareGeographicBoundingBoxes(geographicExtent, \ 
    93                                                   ceda_observationCollection.geographicExtent[0])): 
    94                 self.epbRepo.moles3EPB.updateCedaObject(ceda_observationCollection, \ 
    95                                                 {'geographicExtent': geographicExtent})                         
    96         else: 
    97             self._report.append(NoGeographicalExtensionException(self._dataEntityMigration))           
     80        bbox = self.epbRepo.moles3EPB.\ 
     81                    getUnifyObservationCollectionGEAsBBox(ceda_observationCollection) 
     82         
     83        if bbox is None: 
     84            self._report.\ 
     85                    append(NoGeographicalExtensionException(self._dataEntityMigration)) 
     86            return             
     87 
     88        upperCornerData, lowerCornerData = bbox[4:len(bbox)-1].split(',') 
     89        east, north = upperCornerData.split() 
     90        west, south = lowerCornerData.split() 
     91        geographicExtent = create_ex_geographic_boundingbox(float(east),  
     92                                                            float(north),  
     93                                                            float(west),  
     94                                                            float(south)) 
     95         
     96        if len(ceda_observationCollection.geographicExtent) == 0 or \ 
     97            (len(ceda_observationCollection.geographicExtent) > 0 and \ 
     98                not compareGeographicBoundingBoxes(geographicExtent, \ 
     99                                        ceda_observationCollection.geographicExtent[0])): 
     100            self.epbRepo.moles3EPB.updateCedaObject(ceda_observationCollection,  
     101                                            {'geographicExtent': geographicExtent})                         
     102                       
    98103         
    99104    def _assignPhenomenonTime(self, ceda_observationCollection): 
     
    102107        if end is not None: 
    103108            dateString = '%s/%s' % (start, end) 
    104         pt = from_date_string_to_pt(dateString) 
     109        pt = from_date_string_to_pt(start, end) 
    105110         
    106111        if pt is not None \ 
     
    301306                self._assignObservationCollectionToProject(obs_coll, ceda_observation)                     
    302307            except Exception as ex: 
    303                 self._report.append(ex)                 
     308                self._report.append(ex) 
    304309                         
    305310        self._assignGeographicExtent(obs_coll) 
  • mauRepo/MolesManager/trunk/cedaMoles/libs/migration/processor/deployment.py

    r8538 r8545  
    540540            return   
    541541               
    542         doc_phenomenon_time = extract_moles_temporal_range(self._deployment_migration)  
    543         pt = from_date_string_to_pt(doc_phenomenon_time)     
    544          
     542        doc_phenomenon_time = extract_moles_temporal_range(self._deployment_migration) 
     543         
     544        start, end = doc_phenomenon_time, None 
     545        if '/' in doc_phenomenon_time: 
     546            start, end = doc_phenomenon_time.split('/') 
     547        pt = from_date_string_to_pt(start, end)  
    545548        if self._deploymentHasBeenProcessed \ 
    546549                or observation.phenomenonTime is not None \ 
    547550                and not compare_phenomenon_times(pt,observation.phenomenonTime): 
    548551            self.epbRepo.moles3EPB.updateCedaObject(observation, {'phenomenonTime': pt}) 
    549             #Now update phenomenonTime but has to remove the previous phenomenonTime 
    550              
     552            #Now update phenomenonTime but has to remove the previous phenomenonTime         
    551553        elif not self._deploymentHasBeenProcessed: 
    552554            observation.phenomenonTime = pt                 
    553                  
    554555    def _assignPermission(self, observation): 
    555556        if self._deploymentHasSameHash and self._dataEntityHasSameHash: 
  • mauRepo/MolesManager/trunk/cedaMoles/tests/migration/commontest.py

    r8496 r8545  
    66from unittest import TestCase 
    77from cedaMoles.libs.migration.processor.commons import isoDateTimeStringToTimeDate,\ 
    8     from_date_string_to_pt, from_pt_to_string,\ 
     8    from_date_string_to_pt,\ 
    99    compare_phenomenon_times 
    1010 
     
    3131        temporalRange = '2002-07-22/2011-08-06' 
    3232        pt = from_date_string_to_pt(temporalRange) 
    33         ptString = from_pt_to_string(pt) 
    3433        startDate, endDate = temporalRange.split('/')         
    35         self.assertTrue(startDate == ptString[0], "Error")         
    36         self.assertTrue(endDate == ptString[1], "Error")         
     34        self.assertTrue(startDate == pt.start.ceda_timestamp, "Error")         
     35        self.assertTrue(endDate == pt.end.ceda_timestamp, "Error")         
    3736         
    3837        temporalRange = '2002-07-22' 
    3938        pt = from_date_string_to_pt(temporalRange) 
    40         ptString = from_pt_to_string(pt) 
    4139        startDate, endDate = temporalRange, None         
    42         self.assertTrue(startDate == ptString[0], "Error")         
    43         self.assertTrue(endDate == ptString[1], "Error") 
     40        self.assertTrue(startDate == pt.start.ceda_timestamp, "Error")         
     41        self.assertTrue(endDate == pt.end.ceda_timestamp, "Error")     
    4442         
    4543    def testComparePhenomenonTimes(self): 
Note: See TracChangeset for help on using the changeset viewer.