class ProdHeader(Base): __tablename__ = "production_header" api10 = db.Column(db.String(10), primary_key=True) primary_api14 = db.Column(db.String(14), index=True) entity12 = db.Column(db.String(12), nullable=False) status = db.Column(db.String()) first_prod_date = db.Column(db.Date()) last_prod_date = db.Column(db.Date()) prod_months = db.Column(db.Integer()) prod_days = db.Column(db.Integer()) peak_norm_months = db.Column(db.Integer()) peak_norm_days = db.Column(db.Integer()) peak30_oil = db.Column(db.Integer()) peak30_gas = db.Column(db.Integer()) peak30_date = db.Column(db.Date()) peak30_month = db.Column(db.Integer()) perfll = db.Column(db.Integer()) perf_upper = db.Column(db.Integer()) perf_lower = db.Column(db.Integer()) oil_pdp_last3mo_per30kbbl = db.Column(db.Integer()) boe_pdp_last3mo_per30kbbl = db.Column(db.Integer()) products = db.Column(db.String()) provider = db.Column(db.String()) provider_last_update_at = db.Column(db.DateTime(timezone=True)) related_well_count = db.Column(db.Integer()) related_wells = db.Column(db.JSONB(), nullable=False, server_default="[]") comments = db.Column(db.JSONB(), nullable=False, server_default="{}")
class WellStat(WellBase): __tablename__ = "wellstats" name = db.Column(db.String(50), primary_key=True) type = db.Column(db.String(25), nullable=False) # numeric, string, date numeric_value = db.Column(db.Numeric(19, 2)) string_value = db.Column(db.Numeric(19, 2)) date_value = db.Column(db.Numeric(19, 2)) comments = db.Column(db.JSONB(), nullable=False, server_default="{}")
class Area(Base): __tablename__ = "areas" id = db.Column(db.Integer(), primary_key=True, autoincrement=True) area = db.Column(db.String(25), unique=True, nullable=False) h_last_run_at = db.Column(db.DateTime(timezone=True)) v_last_run_at = db.Column(db.DateTime(timezone=True)) providers = db.Column(db.JSONB(), nullable=False, server_default="[]") # entity_type = db.Column( # db.ChoiceType(EntityType, impl=db.String()), primary_key=True # ) # hole_direction = db.Column( # db.ChoiceType(HoleDirection, impl=db.String()), primary_key=True # ) @classmethod def _is_ready(cls, last_run_at: Optional[datetime], cooldown_hours: int): if last_run_at: utcnow = datetime.now().astimezone(pytz.utc) threshold = utcnow - timedelta(hours=cooldown_hours) return last_run_at < threshold else: return True @classmethod async def next_available( cls, hole_dir: HoleDirection) -> Tuple[Area, str, bool, int]: """ Get the properties describing the next available execution time of the given hole direction and entity type """ if hole_dir == HoleDirection.H: cooldown = conf.PRODSTATS_H_COOLDOWN elif hole_dir == HoleDirection.V: cooldown = conf.PRODSTATS_V_COOLDOWN else: cooldown = ONE_WEEK attr = f"{hole_dir.value.lower()}_last_run_at" area_obj = await cls.query.order_by( # get stalest area for given hole_dir getattr(cls, attr).asc().nullsfirst()).gino.first() is_ready = cls._is_ready(getattr(area_obj, attr), cooldown) logger.info( f"({cls.__name__}[{hole_dir}]) next available: {area_obj.area} {is_ready=}" # noqa ) return area_obj, attr, is_ready, cooldown @classmethod async def df(cls) -> pd.DataFrame: records = await cls.query.gino.all() return pd.DataFrame([x.to_dict() for x in records], columns=cls.c.names).set_index("area")
class ProdMonthly(Base): __tablename__ = "production_monthly" api10 = db.Column(db.String(10), primary_key=True) prod_date = db.Column(db.Date(), primary_key=True) prod_month = db.Column(db.Integer()) days_in_month = db.Column(db.Integer()) prod_days = db.Column(db.Integer()) peak_norm_month = db.Column(db.Integer()) peak_norm_days = db.Column(db.Integer()) # currently prod_day oil = db.Column(db.Integer()) gas = db.Column(db.Integer()) water = db.Column(db.Integer()) boe = db.Column(db.Integer()) water_cut = db.Column(db.Numeric(19, 2)) oil_percent = db.Column(db.Numeric(19, 2)) gor = db.Column(db.Integer()) oil_per1k = db.Column(db.Integer()) gas_per1k = db.Column(db.Integer()) water_per1k = db.Column(db.Integer()) boe_per1k = db.Column(db.Integer()) gas_per3k = db.Column(db.Integer()) oil_per3k = db.Column(db.Integer()) water_per3k = db.Column(db.Integer()) boe_per3k = db.Column(db.Integer()) gas_per5k = db.Column(db.Integer()) oil_per5k = db.Column(db.Integer()) water_per5k = db.Column(db.Integer()) boe_per5k = db.Column(db.Integer()) gas_per7500 = db.Column(db.Integer()) oil_per7500 = db.Column(db.Integer()) water_per7500 = db.Column(db.Integer()) boe_per7500 = db.Column(db.Integer()) gas_per10k = db.Column(db.Integer()) oil_per10k = db.Column(db.Integer()) water_per10k = db.Column(db.Integer()) boe_per10k = db.Column(db.Integer()) oil_avg_daily = db.Column(db.Integer()) gas_avg_daily = db.Column(db.Numeric(19, 2)) water_avg_daily = db.Column(db.Numeric(19, 2)) boe_avg_daily = db.Column(db.Numeric(19, 2)) comments = db.Column(db.JSONB(), nullable=False, server_default="{}")
class ProdStat(Base): __tablename__ = "prodstats" api10 = db.Column(db.String(10), primary_key=True) name = db.Column(db.String(50), primary_key=True, index=True) value = db.Column(db.Numeric(19, 2)) property_name = db.Column(db.String(50), index=True) aggregate_type = db.Column(db.String(25), index=True) is_peak_norm = db.Column(db.Boolean()) is_ll_norm = db.Column(db.Boolean()) ll_norm_value = db.Column(db.Integer()) includes_zeroes = db.Column(db.Boolean()) start_date = db.Column(db.Date()) end_date = db.Column(db.Date()) start_month = db.Column(db.Integer()) end_month = db.Column(db.Integer()) comments = db.Column(db.JSONB(), nullable=False, server_default="{}") ix_prodstat_api10_prop_agg = db.Index("ix_prodstat_api10_prop_agg", "api10", "property_name", "aggregate_type")