'commit'
This commit is contained in:
113
Model/StationStatus.py
Normal file
113
Model/StationStatus.py
Normal file
@@ -0,0 +1,113 @@
|
||||
from sqlalchemy import text
|
||||
from datetime import datetime
|
||||
import json
|
||||
|
||||
class StationStatus:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
async def save(self, session, id, station_hash, total_piles, free_piles, piles_detail_json, current_price, pro_price=None, parking_info=None, distance=None, valid_start_time=None):
|
||||
if valid_start_time is None:
|
||||
valid_start_time = datetime.now()
|
||||
|
||||
# Ensure json is string with consistent formatting
|
||||
piles_json_str = None
|
||||
if piles_detail_json is not None:
|
||||
if isinstance(piles_detail_json, (dict, list)):
|
||||
piles_json_str = json.dumps(piles_detail_json, ensure_ascii=False, sort_keys=True)
|
||||
else:
|
||||
piles_json_str = piles_detail_json
|
||||
|
||||
# 1. Check current record
|
||||
select_sql = """
|
||||
SELECT total_piles, free_piles, piles_detail_json, current_price, pro_price, parking_info, distance
|
||||
FROM t_station_status_scd
|
||||
WHERE station_hash = :station_hash AND is_current = 1
|
||||
"""
|
||||
try:
|
||||
result = await session.execute(text(select_sql), {"station_hash": station_hash})
|
||||
current_row = result.fetchone()
|
||||
except Exception as e:
|
||||
# Check if it's a "column not found" error
|
||||
if "Unknown column 'parking_info'" in str(e) or "no such column: parking_info" in str(e):
|
||||
# Handle schema evolution if needed, or just proceed assuming None for parking_info comparison
|
||||
current_row = None
|
||||
# Or re-raise if we want to fail hard, but let's try to be robust
|
||||
# For now, if column missing, we might fail on INSERT later anyway.
|
||||
# So re-raising or logging might be better.
|
||||
# But since I cannot easily alter table here, I will proceed with code update
|
||||
# and assume user/I run the ALTER script.
|
||||
raise e
|
||||
raise e
|
||||
|
||||
if current_row:
|
||||
# Check if changed
|
||||
# Note: current_row values might be Decimal, need to convert for comparison
|
||||
row_total = current_row.total_piles
|
||||
row_free = current_row.free_piles
|
||||
row_json = current_row.piles_detail_json
|
||||
row_price = current_row.current_price
|
||||
row_pro_price = current_row.pro_price
|
||||
row_parking = getattr(current_row, 'parking_info', None) # Safely get if column exists
|
||||
row_distance = getattr(current_row, 'distance', None)
|
||||
|
||||
# Normalize row_json for comparison (handle key order differences)
|
||||
if row_json:
|
||||
try:
|
||||
if isinstance(row_json, str):
|
||||
row_json_obj = json.loads(row_json)
|
||||
row_json = json.dumps(row_json_obj, ensure_ascii=False, sort_keys=True)
|
||||
except Exception:
|
||||
pass # Keep original if parse fails
|
||||
|
||||
# Convert price to float if it is Decimal, for comparison
|
||||
if row_price is not None:
|
||||
row_price = float(row_price)
|
||||
if row_pro_price is not None:
|
||||
row_pro_price = float(row_pro_price)
|
||||
|
||||
# Simple comparison
|
||||
is_same = (
|
||||
row_total == total_piles and
|
||||
row_free == free_piles and
|
||||
row_price == current_price and
|
||||
row_pro_price == pro_price and
|
||||
row_json == piles_json_str and
|
||||
row_parking == parking_info and
|
||||
row_distance == distance
|
||||
)
|
||||
|
||||
if is_same:
|
||||
# No change, skip insert
|
||||
return
|
||||
|
||||
# Expire old record
|
||||
update_sql = """
|
||||
UPDATE t_station_status_scd
|
||||
SET is_current = 0, valid_end_time = :valid_start_time
|
||||
WHERE station_hash = :station_hash AND is_current = 1
|
||||
"""
|
||||
await session.execute(text(update_sql), {
|
||||
"valid_start_time": valid_start_time,
|
||||
"station_hash": station_hash
|
||||
})
|
||||
|
||||
# 2. Insert new record
|
||||
sql = """
|
||||
INSERT INTO t_station_status_scd
|
||||
(id, station_hash, total_piles, free_piles, piles_detail_json, current_price, pro_price, parking_info, distance, valid_start_time, is_current)
|
||||
VALUES
|
||||
(:id, :station_hash, :total_piles, :free_piles, :piles_detail_json, :current_price, :pro_price, :parking_info, :distance, :valid_start_time, 1)
|
||||
"""
|
||||
await session.execute(text(sql), {
|
||||
"id": id,
|
||||
"station_hash": station_hash,
|
||||
"total_piles": total_piles,
|
||||
"free_piles": free_piles,
|
||||
"piles_detail_json": piles_json_str,
|
||||
"current_price": current_price,
|
||||
"pro_price": pro_price,
|
||||
"parking_info": parking_info,
|
||||
"distance": distance,
|
||||
"valid_start_time": valid_start_time
|
||||
})
|
||||
Reference in New Issue
Block a user