-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update fix/consolidated data cleanup #4203
Changes from all commits
555c5b4
da227a4
a77c550
d9da775
a4e9bcd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,6 +1,8 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
import numpy as np | ||||||||||||||||||||||||||||||||||||||||||||||||||||
import pandas as pd | ||||||||||||||||||||||||||||||||||||||||||||||||||||
import logging | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
from .config import configuration | ||||||||||||||||||||||||||||||||||||||||||||||||||||
from .bigquery_api import BigQueryApi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
from .constants import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
DeviceCategory, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -14,6 +16,8 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||
from .data_validator import DataValidationUtils | ||||||||||||||||||||||||||||||||||||||||||||||||||||
from typing import List, Dict, Any, Optional, Union | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
logger = logging.getLogger(__name__) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
class DataUtils: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Device_Field_Mapping = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -70,40 +74,17 @@ def extract_data_from_bigquery( | |||||||||||||||||||||||||||||||||||||||||||||||||||
bigquery_api = BigQueryApi() | ||||||||||||||||||||||||||||||||||||||||||||||||||||
table: str = None | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
source = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
DataType.RAW: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
DeviceCategory.GENERAL: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Frequency.RAW: bigquery_api.raw_measurements_table, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
DeviceCategory.BAM: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Frequency.RAW: bigquery_api.raw_bam_measurements_table | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
DeviceCategory.WEATHER: {Frequency.RAW: bigquery_api.raw_weather_table}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
DataType.AVERAGED: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
DeviceCategory.GENERAL: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Frequency.HOURLY: bigquery_api.hourly_measurements_table, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Frequency.DAILY: bigquery_api.daily_measurements_table, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
DeviceCategory.BAM: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Frequency.HOURLY: bigquery_api.bam_hourly_measurements_table | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
DeviceCategory.WEATHER: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Frequency.RAW: bigquery_api.hourly_weather_table | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
DataType.CONSOLIDATED: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
DeviceCategory.GENERAL: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Frequency.HOURLY: bigquery_api.consolidated_data_table, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}.get(datatype, None) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
if not device_category: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
device_category = DeviceCategory.GENERAL | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
if source: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
source = configuration.DataSource.get(datatype) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
table = source.get(device_category).get(frequency) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
except KeyError as e: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
logger.exception( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
f"Invalid combination: {datatype}, {device_category}, {frequency}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
except Exception as e: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
logger.exception("An unexpected error occurred during column retrieval") | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
if not table: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
raise ValueError("No table information provided.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -121,6 +102,43 @@ def extract_data_from_bigquery( | |||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
return raw_data | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
def format_data_for_bigquery( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
data: pd.DataFrame, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
datatype: DataType, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
device_category: DeviceCategory, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
frequency: Frequency, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) -> pd.DataFrame: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Formats a pandas DataFrame for BigQuery by ensuring all required columns are present | ||||||||||||||||||||||||||||||||||||||||||||||||||||
and the timestamp column is correctly parsed to datetime. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
Args: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
data (pd.DataFrame): The input DataFrame to be formatted. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
data_type (DataType): The type of data (e.g., raw, averaged or processed). | ||||||||||||||||||||||||||||||||||||||||||||||||||||
device_category (DeviceCategory): The category of the device (e.g., BAM, low-cost). | ||||||||||||||||||||||||||||||||||||||||||||||||||||
frequency (Frequency): The data frequency (e.g., raw, hourly, daily). | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
Returns: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
pd.DataFrame: A DataFrame formatted for BigQuery with required columns populated. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
Raises: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
KeyError: If the combination of data_type, device_category, and frequency is invalid. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Exception: For unexpected errors during column retrieval or data processing. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
data.loc[:, "timestamp"] = pd.to_datetime(data["timestamp"]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
datasource = configuration.DataSource | ||||||||||||||||||||||||||||||||||||||||||||||||||||
cols = datasource.get(datatype).get(device_category).get(frequency) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
except KeyError as e: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
logger.exception( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
f"Invalid combination: {datatype}, {device_category}, {frequency}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
except Exception as e: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
logger.exception("An unexpected error occurred during column retrieval") | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
return Utils.populate_missing_columns(data=data, columns=cols) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+130
to
+140
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Initialize cols variable and improve error handling. The cols variable could be undefined if an exception occurs, and the error handling could be more informative. Apply this diff: + cols = []
try:
datasource = configuration.DataSource
cols = datasource.get(datatype).get(device_category).get(frequency)
except KeyError as e:
logger.exception(
- f"Invalid combination: {datatype}, {device_category}, {frequency}"
+ f"Invalid combination: {datatype}, {device_category}, {frequency}. Error: {str(e)}"
)
+ raise
except Exception as e:
logger.exception("An unexpected error occurred during column retrieval")
+ raise
return Utils.populate_missing_columns(data=data, columns=cols) 📝 Committable suggestion
Suggested change
🧰 Tools🪛 Ruff (0.8.2)133-133: Local variable Remove assignment to unused variable (F841) 137-137: Local variable Remove assignment to unused variable (F841) |
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
@staticmethod | ||||||||||||||||||||||||||||||||||||||||||||||||||||
def remove_duplicates( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
data: pd.DataFrame, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance error handling by including original error messages.
The current error handling loses valuable context by not including the original error message in the logs.
Apply this diff to improve error handling:
📝 Committable suggestion
🧰 Tools
🪛 Ruff (0.8.2)
82-82: Local variable
e
is assigned to but never usedRemove assignment to unused variable
e
(F841)
86-86: Local variable
e
is assigned to but never usedRemove assignment to unused variable
e
(F841)