윤영준 윤영준 2023-10-22
also, weather data update now supports DB
@10bd22275e455a47ebe2e5829ba4abc52a3ca6ea
tools/weather_agency_api/weather_api.py
--- tools/weather_agency_api/weather_api.py
+++ tools/weather_agency_api/weather_api.py
@@ -1,13 +1,33 @@
 import os
+import numpy as np
 import pandas as pd
 import requests
+import psycopg2
 from datetime import datetime, timedelta
 from io import StringIO
 from tools.weather_agency_api.duplicate_check import duplicate_check
 from tools.weather_agency_api.check_missing import check_missing
 from sqlalchemy import create_engine
 
-DATABASE_URL = "postgresql+psycopg2://username:ts4430!@@localhost:5432/welding"
+def buck_equation(temperature): # temp in Celsius
+    saturation_vapor_pressure = 0.61121 * np.exp((18.678-temperature/234.5)*(temperature/(257.14+temperature)))
+    return saturation_vapor_pressure * 1000 # KPa -> Pa
+
+def absolute_humidity(relative_humidity, temperature):
+    relative_humidity = np.array(relative_humidity)
+    temperature = np.array(temperature)
+    saturation_vapor_pressure = buck_equation(temperature)
+    # 461.5/Kg Kelvin is specific gas constatnt
+    return saturation_vapor_pressure * relative_humidity * 0.01 /(461.5 * (temperature + 273.15) ) # g/m^3
+
+db_info ={
+    'dbname': 'welding',
+    'user': 'postgres',
+    'password': 'ts4430!@',
+    'host': 'localhost',  # e.g., 'localhost'
+    'port': '5432',  # e.g., '5432'
+}
+
 # https://apihub.kma.go.kr/ 참고
 weather_api_columns = [
     "관측시각",
@@ -88,16 +108,18 @@
     Updates the weather information up to today at 00:00.
     """
 
-    # Set up a connection using SQLAlchemy (for Pandas operations)
-    engine = create_engine(DATABASE_URL)
+    # Set up a connection using psycopg2
+    conn = psycopg2.connect(**db_info)
+
+    # Create a cursor object
+    cursor = conn.cursor()
 
     # Load existing data
     query = "SELECT * FROM weather_data"
-    df_weather_existing = pd.read_sql(query, engine)
+    df_weather_existing = pd.read_sql(query, conn)
 
     # Find the last date available in the database
-    last_date_str = f'{df_weather_existing.iloc[-1]["관측시각"]}'
-    last_date = datetime.strptime(last_date_str, '%Y%m%d%H%M')
+    last_date = df_weather_existing.iloc[-1].loc['time']
 
     # Get today's date at 00:00
     today_00 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
@@ -116,22 +138,44 @@
                 end_day = date + k
             else:
                 end_day = len(date_lists) - 1
-            text = call_administration_of_weather_api(date_lists[date], date_lists[end_day])  # Ensure this function is defined
+            text = call_administration_of_weather_api(date_lists[date], date_lists[end_day])
             buffer = StringIO(text)
-            df = pd.read_csv(buffer, skiprows=2, skipfooter=1, sep=r"\s+", header=None, index_col=False, engine="python").iloc[2:, :-1]
-            df = df.set_axis(weather_api_columns, axis=1, inplace=False)  # Ensure 'weather_api_columns' is defined
-            if not check_missing(df):  # Ensure this function is defined
+            df = pd.read_csv(buffer, skiprows=2, skipfooter=1, sep=r"\s+", header=None, index_col=False,
+                             engine="python").iloc[2:, :-1]
+            df = df.set_axis(weather_api_columns, axis=1, inplace=False)
+            if not check_missing(df):
                 print("API is not working!")
                 return {
                     "responses": 500
                 }
             df_weather_new = pd.concat([df_weather_new, df], ignore_index=True)
+            df_weather_new = df_weather_new.loc[:,["관측시각", "기온", "상대습도"]]
+            df_weather_new['관측시각'] = pd.to_datetime(df_weather_new['관측시각'], format='%Y%m%d%H%M')
+            df_weather_new = df_weather_new.rename(columns={
+                '관측시각': 'time',
+                '기온': 'temperature',
+                '상대습도': 'relative_humidity',
+            },
+                inplace=False
+            )
+            df_weather_new['absolute_humidity'] = absolute_humidity(df_weather_new['relative_humidity'].astype(float), df_weather_new['temperature'].astype(float))
+
             print(f"{i}/{len(range(0, len(date_lists) - 1, k)) - 1}")
 
         # Append the new data to the existing data in the database
-        df_weather_new.to_sql('weather_data', engine, if_exists='append', index=False)
+        for _, row in df_weather_new.iterrows():
+            columns = ','.join(row.keys())
+            values = ','.join([f"'{item}'" for item in row])
+            cursor.execute(f"INSERT INTO weather_data ({columns}) VALUES ({values})")
+
+        conn.commit()
     else:
         print("Weather data is already up-to-date!")
+
+    # Close the cursor and the connection
+    cursor.close()
+    conn.close()
+
 
 def update_weather_info_to_today_csv(file_name):
     """
@@ -178,6 +222,9 @@
             print(f"{i}/{len(range(0, len(date_lists) - 1, k)) - 1}")
 
         # Append the new data to the existing data
+        df_weather_new['관측시각'] = df_weather_new['관측시각'].apply(lambda x: datetime.strptime(f"{x}", '%Y%m%d%H%M'))
+        df_weather_upload = df_weather_new['관측시간','기온','상대습도']
+
         df_weather_updated = pd.concat([df_weather_existing, df_weather_new], ignore_index=True)
         df_weather_updated = duplicate_check(df_weather_updated)
         df_weather_updated.to_csv(file_name, index=False)
@@ -187,4 +234,4 @@
 
 if __name__ == "__main__":
     file = "202007010000_202308310000.csv"
-    update_weather_info_to_today(file)
+    update_weather_info_to_today()
Add a comment
List