class WZFeatureDataAccess(DataAccess): def __init__(self, **kwargs): super().__init__(**kwargs) self.da_base = DataAccessBase(model.WorkZoneFeature, WorkZoneFeatureInfo, **kwargs) def list(self, wz_id, **kwargs): """ :type wz_id: int :rtype: list[WorkZoneFeatureInfo] or list[model.WorkZoneFeature] """ return self.da_base.search([('wz_id', wz_id)], cond='match', **kwargs) def list_by_wz_ids(self, wz_ids, **kwargs): """ :type wz_ids: list[int] :rtype: Union(list[WorkZoneFeatureInfo], list[model.WorkZoneFeature]) """ if not wz_ids: return [] as_model = kwargs.get('as_model', False) window_size = kwargs.get('window_size', 1000) sess = self.da_base.session dbModel = self.da_base.dbModel qry = sess.query(dbModel).filter(dbModel.wz_id.in_(wz_ids)) for m in self.da_base.query_generator(qry, window_size): if as_model: yield m else: yield self.da_base.to_info(m) def get_by_id(self, wzf_id): """ :type wzf_id: int :rtype: pyticas_tetres.ttypes.WorkZoneFeatureInfo """ return self.da_base.get_data_by_id(wzf_id) def get_by_wzid(self, wz_id): """ :type wz_id: int :rtype: list[pyticas_tetres.ttypes.WorkZoneFeatureInfo] """ return self.da_base.search([('wz_id', wz_id)]) def insert(self, wzfi, **kwargs): """ :type wzfi: pyticas_tetres.ttypes.WorkZoneFeatureInfo :rtype: model.WorkZoneFeature """ return self.da_base.insert(wzfi, **kwargs)
class RouteWiseMOEParametersDataAccess(DataAccess): def __init__(self, **kwargs): super().__init__(**kwargs) self.da_base = DataAccessBase(model.RouteWiseMOEParameters, RouteWiseMOEParametersInfo, **kwargs) def list(self): """ :rtype: list[pyticas_tetres.ttypes.WorkZoneGroupInfo] """ data_list = self.da_base.list( order_by=[('reference_tt_route_id', 'asc'), ('start_time', 'asc'), ('end_time', 'asc'), ('status', 'asc')]) for data in data_list: data.start_time = str(data.start_time) if data.start_time else "" data.end_time = str(data.end_time) if data.end_time else "" data.update_time = str( data.update_time) if data.update_time else "" return data_list def get_by_id(self, moe_param_id): """ :type wz_id: int :rtype: pyticas_tetres.ttypes.WorkZoneGroupInfo """ return self.da_base.get_data_by_id(moe_param_id) def insert(self, route_wise_moe_param_info, **kwargs): """ :type wzi: pyticas_tetres.ttypes.WorkZoneGroupInfo :rtype: model.WorkZoneGroup """ return self.da_base.insert(route_wise_moe_param_info, **kwargs) def search_by_route_id(self, route_id, *args, **kwargs): return self.da_base.search([('reference_tt_route_id', route_id)]) def get_latest_moe_param_for_a_route(self, route_id, *args, **kwargs): latest_object = None data_list = self.search_by_route_id(route_id, *args, **kwargs) if not data_list: return latest_object latest_update_time = data_list[0].update_time latest_object = data_list[0] for data in data_list: if data.update_time > latest_update_time: latest_update_time = data.update_time latest_object = data return latest_object
class WZGroupDataAccess(DataAccess): def __init__(self, **kwargs): super().__init__(**kwargs) self.da_base = DataAccessBase(model.WorkZoneGroup, WorkZoneGroupInfo, **kwargs) def list(self): """ :rtype: list[pyticas_tetres.ttypes.WorkZoneGroupInfo] """ return self.da_base.list() def list_by_year(self, years): """ :type years: list[int] :return: """ if years: wheres = [('years', y) for y in years] return self.da_base.search(wheres, op='or', cond='like') else: return self.da_base.search([('years', None), ('years', '')], op='or', cond='match') def years(self): """ :rtype: list[int]: """ ys = [] for wzi in self.da_base.list(): if not wzi.years: continue for y in wzi.years.split(','): iy = int(y) if iy not in ys: ys.append(iy) return sorted(ys) def get_by_id(self, wz_id): """ :type wz_id: int :rtype: pyticas_tetres.ttypes.WorkZoneGroupInfo """ return self.da_base.get_data_by_id(wz_id) def get_by_name(self, wz_name): """ :type wz_name: str :rtype: pyticas_tetres.ttypes.WorkZoneGroupInfo """ return self.da_base.get_data_by_name(wz_name) def insert(self, wzi, **kwargs): """ :type wzi: pyticas_tetres.ttypes.WorkZoneGroupInfo :rtype: model.WorkZoneGroup """ return self.da_base.insert(wzi, **kwargs) def update_years(self, id, **kwargs): """ :type id: int :rtype: bool """ wzgm = self.da_base.get_model_by_id(id) years = [] for wzm in wzgm._wzs: syear = wzm.start_time.year eyear = wzm.end_time.year for y in range(syear, eyear + 1): y = str(y) if y not in years: years.append(y) return self.update(id, {'years': ','.join(years)}, **kwargs) def search(self, searches, op='and', cond='match', **kwargs): """ search data **Example** - find item that `sevent_id` is 1 >>> search([('sevent_id', 1)] - find item that `name` == 'test and start_time == 2016-01-01 00:00 and end_time == 2016-01-01 07:00 >>> search([('name', 'test'), ('start_time', datetime(2016, 1, 1, 0, 0)), ('end_time', 2016, 1, 1, 7, 0)], op='and', cond='match') - find items that `years` contains one of 2014, 2015 and 2016 >>> search([('years', y) for y in [2014, 2015, 2016]], op='or', cond='like') """ return self.da_base.search(searches, op, cond, **kwargs)
class WorkZoneDataAccess(DataAccess): def __init__(self, **kwargs): super().__init__(**kwargs) self.da_base = DataAccessBase(model.WorkZone, WorkZoneInfo, **kwargs) def list(self, **kwargs): """ :rtype: list[pyticas_tetres.ttypes.WorkZoneInfo] """ return self.da_base.list(**kwargs) def list_by_year(self, years): """ :type years: list[int] :return: """ wheres = [('years', y) for y in years] return self.da_base.search(wheres, op='or', cond='like') def years(self): """ :rtype: list[int]: """ ys = [] for wzi in self.da_base.list(): for y in wzi.years.split(','): iy = int(y) if iy not in ys: ys.append(iy) return sorted(ys) def get_model_by_id(self, wz_id): """ :type wz_id: int :rtype: pyticas_tetres.db.model.WorkZone """ return self.da_base.get_model_by_id(wz_id) def get_by_id(self, wz_id): """ :type wz_id: int :rtype: pyticas_tetres.ttypes.WorkZoneInfo """ return self.da_base.get_data_by_id(wz_id) def get_by_name(self, wz_name): """ :type wz_name: str :rtype: pyticas_tetres.ttypes.WorkZoneInfo """ return self.da_base.get_data_by_name(wz_name) def insert(self, wzi, **kwargs): """ :type wzi: pyticas_tetres.ttypes.WorkZoneInfo :rtype: model.WorkZone """ return self.da_base.insert(wzi, **kwargs) def search(self, searches, op='and', cond='match', **kwargs): """ search data **Example** - find item that `sevent_id` is 1 >>> search([('sevent_id', 1)] - find item that `name` == 'test and start_time == 2016-01-01 00:00 and end_time == 2016-01-01 07:00 >>> search([('name', 'test'), ('start_time', datetime(2016, 1, 1, 0, 0)), ('end_time', 2016, 1, 1, 7, 0)], op='and', cond='match') - find items that `years` contains one of 2014, 2015 and 2016 >>> search([('years', y) for y in [2014, 2015, 2016]], op='or', cond='like') """ return self.da_base.search(searches, op, cond, **kwargs) def search_date_range(self, sdt, edt, **kwargs): """ search data overlapped with the given data range :type sdt: datetime.datetime :type sdt: datetime.datetime :rtype: list[pyticas_tetres.ttypes.WorkZoneInfo] """ as_model = kwargs.get('as_model', False) clauses = or_() clauses = or_(clauses, self.da_base.dbModel.end_time < sdt) clauses = or_(clauses, self.da_base.dbModel.start_time > edt) clauses = not_(clauses) data_list = [] for model_data in self.da_base.session.query( self.da_base.dbModel).filter(clauses): if as_model: data_list.append(model_data) else: data_list.append(self.da_base.to_info(model_data)) return data_list
class SnowMgmtDataAccess(DataAccess): def __init__(self, **kwargs): super().__init__(**kwargs) self.da_base = DataAccessBase(model.SnowManagement, SnowManagementInfo, **kwargs) def list(self, **kwargs): """ :rtype: list[SnowManagementInfo] """ return self.da_base.list(**kwargs) def list_by_period(self, sdt, edt, **kwargs): """ :type sdt: datetime.datetime :type edt: datetime.datetime :rtype: list[SnowManagementInfo] """ sdt = sdt.replace(second=0, microsecond=0) edt = edt.replace(second=59, microsecond=59) qry = (self.da_base.session.query(self.da_base.dbModel).join( model.SnowEvent).filter( or_( and_(model.SnowEvent.start_time <= sdt, model.SnowEvent.end_time >= sdt), and_(model.SnowEvent.start_time >= sdt, model.SnowEvent.end_time <= edt), and_(model.SnowEvent.start_time <= edt, model.SnowEvent.end_time >= edt), ))) data_list = [] for model_data in qry: data_list.append(self.da_base.to_info(model_data, **kwargs)) return data_list def get_by_id(self, route_id): """ :type route_id: int :rtype: SnowManagementInfo """ return self.da_base.get_data_by_id(route_id) def get_by_name(self, route_name): """ :type route_name: str :rtype: SnowManagementInfo """ return self.da_base.get_data_by_name(route_name) def insert(self, r, **kwargs): """ :type r: SnowManagementInfo :rtype: model.SnowManagement """ return self.da_base.insert(r, **kwargs) def search(self, searches, op='and', cond='match', **kwargs): """ :type searches: list :return: """ return self.da_base.search(searches, op=op, cond=cond, **kwargs)
class ActionLogDataAccess(DataAccess): INSERT = 'insert' UPDATE = 'update' DELETE = 'delete' DT_TTROUTE = 'tt_route' DT_WEATHER = 'weather' DT_INCIDENT = 'incident' DT_WORKZONE = 'workzone' DT_WORKZONE_GROUP = 'workzone_group' DT_SPECIALEVENT = 'special_event' DT_SNOWEVENT = 'snow_event' DT_SNOWROUTE = 'snow_route' DT_SNOWMGMT = 'snow_management' DT_SYSTEMCONFIG = 'sysconfig' DT_ROUTE_WISE_MOE_PARAMETERS = 'route_wise_moe_parameters' STATUS_WAIT = 'wait' STATUS_RUNNING = 'running' STATUS_FAIL = 'fail' STATUS_STOPPED = 'stopped' STATUS_DONE = 'done' def __init__(self, **kwargs): super().__init__(**kwargs) self.da_base = DataAccessBase(model.ActionLog, ActionLogInfo, **kwargs) def list(self, start_time=None, action_types=None, handled=None, target_datatypes=None, data_desc=None, status=None, **kwargs): """ :param start_time: e.g. 2013-12-04 12:00:00 :type start_time: Union(str, datetime.datetime) :type action_types: list[str] :type handled: bool :type target_datatypes: list[str] :rtype: list[pyticas_tetres.ttypes.ActionLogInfo] """ if isinstance(start_time, str): start_time = datetime.datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S') as_model = kwargs.get('as_model', False) limit = kwargs.get('limit', None) order_by = kwargs.get('order_by', None) dbModel = model.ActionLog session = self.da_base.session qry = session.query(dbModel) if start_time: qry = qry.filter(dbModel.reg_date >= start_time) if action_types: cond = or_(*[ dbModel.action_type == action_type for action_type in action_types ]) qry = qry.filter(cond) if handled is not None: qry = qry.filter(dbModel.handled == handled) if target_datatypes: cond = or_(*[ dbModel.target_datatype == target_datatype for target_datatype in target_datatypes ]) qry = qry.filter(cond) if data_desc: qry = qry.filter(dbModel.data_desc.like(data_desc)) if status: qry = qry.filter(dbModel.status == status) # apply 'order by' if order_by and isinstance(order_by, tuple): # e.g. order_by = ('id', 'desc') # e.g. order_by = ('name', 'asc') qry = qry.order_by( getattr(getattr(dbModel, order_by[0]), order_by[1])()) else: qry = qry.order_by(dbModel.reg_date.asc()) # apply 'limit' if limit: qry = qry.limit(limit) qry = qry.all() data_list = [] for m in qry: if as_model: data_list.append(m) else: data_list.append(self.da_base.to_info(m)) return data_list def get_by_id(self, pkey): """ :type pkey: int :rtype: Union(list[ActionLogInfo], list[model.ActionLog]) """ return self.da_base.get_data_by_id(pkey) def delete_range(self, start_time=None, end_time=None, action_types=None, handled=None, target_datatypes=None, **kwargs): """ :param start_time: e.g. 2013-12-04 12:00:00 :type start_time: Union(str, datetime.datetime) :param end_time: e.g. 2013-12-04 12:00:00 :type end_time: Union(str, datetime.datetime) :type action_types: list[str] :type handled: bool :type target_datatypes: list[str] :rtype: Union(list[ActionLogInfo], list[model.ActionLog]) """ print_exception = kwargs.get('print_exception', False) if isinstance(start_time, str): start_time = datetime.datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S') if isinstance(end_time, str): end_time = datetime.datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S') dbModel = model.ActionLog session = self.da_base.session qry = session.query(dbModel) if start_time: qry = qry.filter(dbModel.reg_date >= start_time) if end_time: qry = qry.filter(dbModel.reg_date <= end_time) if action_types: cond = or_(*[ dbModel.action_type == action_type for action_type in action_types ]) qry = qry.filter(cond) if handled: qry = qry.filter(dbModel.handled == handled) if target_datatypes: cond = or_(*[ dbModel.target_datatype == target_datatype for target_datatype in target_datatypes ]) qry = qry.filter(cond) try: qry.delete(synchronize_session=False) return True except Exception as ex: if print_exception: tb.traceback(ex) return False def insert(self, r, **kwargs): """ :type r: ActionLogInfo :rtype: model.ActionLog """ return self.da_base.insert(r, **kwargs) def search(self, searches, op='and', cond='match', **kwargs): """ search data **Example** - find item that `sevent_id` is 1 >>> search([('sevent_id', 1)] - find item that `name` == 'test and start_time == 2016-01-01 00:00 and end_time == 2016-01-01 07:00 >>> search([('name', 'test'), ('start_time', datetime(2016, 1, 1, 0, 0)), ('end_time', 2016, 1, 1, 7, 0)], op='and', cond='match') - find items that `years` contains one of 2014, 2015 and 2016 >>> search([('years', y) for y in [2014, 2015, 2016]], op='or', cond='like') :param searches: search condition list (see the above example) :param op: operand ('and', 'or') :param cond: condition ('match', 'like') :param kwargs: if `as_model` is True, returns data as `dbModel` type :rtype: list[pyticas_tetres.ttypes.ActionLogInfo] """ return self.da_base.search(searches, op, cond, **kwargs) @classmethod def data_description(cls, datatype, data): """ :type datatype: str :type data: object :rtype: str """ def _(d, a): attrs = a.split('.') obj = d for attr in attrs: obj = getattr(d, attr, None) if obj == None: break return obj if datatype == ActionLogDataAccess.DT_TTROUTE: return 'Travel Time Route (id=%s, name=%s)' % (_( data, 'id'), _(data, 'name')) if datatype == ActionLogDataAccess.DT_WEATHER: return 'Weather (id=%s, usaf=%s, wban=%s, time=%s)' % (_( data, 'id'), _(data, 'usaf'), _(data, 'wban'), _( data, 'dtime')) if datatype == ActionLogDataAccess.DT_INCIDENT: return ( 'Incident (id=%s, type=%s, time=%s, lat=%s, lon=%s area=%s)' % (_(data, 'id'), _(data, '_incident_type.eventtype'), _(data, 'cdts'), _(data, 'lat'), _(data, 'lon'), _(data, 'earea'))) if datatype == ActionLogDataAccess.DT_WORKZONE_GROUP: return 'Workzone Group (id=%s, name=%s)' % (_( data, 'id'), _(data, 'name')) if datatype == ActionLogDataAccess.DT_WORKZONE: return ( 'Workzone (id=%s, wz_group=%s, start_time=%s, end_time=%s)' % (_(data, 'id'), data._wz_group.name if hasattr(data, '_wz_group') and data._wz_group else None, _(data, 'start_time'), _(data, 'end_time'))) if datatype == ActionLogDataAccess.DT_SPECIALEVENT: return ( 'Special Event (id=%s, name=%s, start_time=%s, end_time=%s)' % (_(data, 'id'), _(data, 'name'), _( data, 'start_time'), _(data, 'end_time'))) if datatype == ActionLogDataAccess.DT_SNOWMGMT: return ( 'Road Condition during Snow Event (id=%s, truck_route=[%s, %s], snow_event=[%s, %s ~ %s], lost=%s, regain=%s)' % (_(data, 'id'), _(data, 'sroute_id'), data._snowroute.name if hasattr(data, '_snowroute') and data._snowroute else None, _(data, 'sevent_id'), data._snowevent.start_time if hasattr(data, '_snowevent') and data._snowevent else None, data._snowevent.end_time if hasattr(data, '_snowevent') and data._snowevent else None, _( data, 'lane_lost_time'), _(data, 'lane_regain_time'))) if datatype == ActionLogDataAccess.DT_SNOWROUTE: return ('Truck Route (id=%s, name=%s, prj_id=%s)' % (_(data, 'id'), _(data, 'name'), _(data, 'prj_id'))) if datatype == ActionLogDataAccess.DT_SNOWEVENT: return ( 'Snow Event (id=%s, start_time=%s, end_time=%s)' % (_(data, 'id'), _(data, 'start_time'), _(data, 'end_time'))) return 'Unknown'
class IrisIncidentDataAccess(object): def __init__(self, **kwargs): kwargs['session'] = conn.get_session() kwargs['primary_key'] = 'event_id' self.da_base = DataAccessBase(model.IrisIncident, IrisIncidentInfo, **kwargs) def list_as_generator(self, sdate, edate, corridor, direction, **kwargs): """ :param sdate: e.g. 2013-12-04 12:00:00 :type sdate: str or datetime.datetime :param edate: e.g. 2013-12-04 13:00:00 :type edate: str or datetime.datetime :param corridor: only number part of corridor name e.g. 35W, 94, 494, 100, 169 :type corridor: str :param direction: e.g. NB, SB, EB, WB :type direction: str :rtype: Generator : IncidentInfo """ if isinstance(sdate, str): sdate = datetime.datetime.strptime(sdate, '%Y-%m-%d %H:%M:%S') if isinstance(edate, str): edate = datetime.datetime.strptime(edate, '%Y-%m-%d %H:%M:%S') as_model = kwargs.get('as_model', False) limit = kwargs.get('limit', None) order_by = kwargs.get('order_by', None) window_size = kwargs.get('window_size', 1000) db_model = model.IrisIncident session = self.da_base.session if corridor and direction: qry = (session.query(db_model).filter( and_(db_model.event_date >= sdate, db_model.event_date <= edate)).filter( and_(db_model.road == corridor, db_model.direction == direction))) else: qry = (session.query(db_model).filter( and_(db_model.event_date >= sdate, db_model.event_date <= edate))) # apply 'order by' if order_by and isinstance(order_by, tuple): # e.g. order_by = ('id', 'desc') # e.g. order_by = ('name', 'asc') qry = qry.order_by( getattr(getattr(db_model, order_by[0]), order_by[1])()) else: qry = qry.order_by(db_model.event_date.asc()) # apply 'limit' if limit: qry = qry.limit(limit) for m in self.da_base.query_generator(qry, window_size): if as_model: yield m else: yield self.da_base.to_info(m) def list(self, sdate, edate, corridor=None, direction=None, **kwargs): """ :param sdate: e.g. 2013-12-04 12:00:00 :type sdate: str or datetime.datetime :param edate: e.g. 2013-12-04 13:00:00 :type edate: str or datetime.datetime :param corridor: only number part of corridor name e.g. 35W, 94, 494, 100, 169 :type corridor: str :param direction: e.g. NB, SB, EB, WB :type direction: str :rtype: list[IrisIncidentInfo] """ return [ m for m in self.list_as_generator(sdate, edate, corridor, direction, **kwargs) ] def get_by_id(self, pkey): """ :type pkey: int :rtype: IrisIncidentInfo """ return self.da_base.get_data_by_id(pkey) def get_by_event_id(self, event_id): """ :type event_id: int :rtype: IrisIncidentInfo """ res = self.da_base.search([('event_id', event_id)]) if res: return res[0] else: return None def close_session(self): self.da_base.close()
class SpecialEventDataAccess(DataAccess): def __init__(self, **kwargs): super().__init__(**kwargs) self.da_base = DataAccessBase(model.Specialevent, SpecialEventInfo, **kwargs) def exist(self, name, start_time, end_time): """ :type name: str :type start_time: str :type end_time: str :rtype: pyticas_tetres.db.model.SpecialEvent """ if isinstance(start_time, str): start_time = datetime.datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S') if isinstance(end_time, str): end_time = datetime.datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S') exs = self.da_base.search([('name', name), ('start_time', start_time), ('end_time', end_time)], op='and', cond='match') return exs def list(self): """ :rtype: list[SpecialEventInfo] """ return self.da_base.list() def list_by_year(self, years): """ :type years: list[int] :rtype: list[SpecialEventInfo] """ wheres = [('years', y) for y in years] return self.da_base.search(wheres, op='or', cond='like') def search_date_range(self, sdt, edt, **kwargs): """ search data overlapped with the given data range :type sdt: datetime.datetime :type sdt: datetime.datetime :rtype: list[pyticas_tetres.ttypes.SpecialEventInfo] """ as_model = kwargs.get('as_model', False) clauses = or_() clauses = or_(clauses, self.da_base.dbModel.end_time < sdt) clauses = or_(clauses, self.da_base.dbModel.start_time > edt) clauses = not_(clauses) data_list = [] for model_data in self.da_base.session.query( self.da_base.dbModel).filter(clauses): if as_model: data_list.append(model_data) else: data_list.append(self.da_base.to_info(model_data)) return data_list def years(self): """ :rtype: list[int]: """ ys = [] for sei in self.da_base.list(): for y in sei.years.split(','): iy = int(y) if iy not in ys: ys.append(iy) return sorted(ys) def get_by_id(self, se_id): """ :type se_id: int :rtype: SpecialEventInfo """ return self.da_base.get_data_by_id(se_id) def insert(self, sei, **kwargs): """ :type sei: SpecialEventInfo """ return self.da_base.insert(sei, **kwargs)