fix(combat): handle JSON string from DB (double-encoded stats_data)
The combat_stats DB column stores stats_data as JSON, but SQLAlchemy returns it as a string (not a parsed dict). This caused: - _combat_lifetime_cache loaded a string, merge failed silently - API endpoints returned string instead of object for lifetime - Frontend saw lifetime as a string, couldn't read .monsters Fix: parse JSON string with json.loads() wherever stats_data is read from DB — in the lifetime cache loader, single-character endpoint, and all-characters endpoint. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0a0fdc5b3d
commit
17f4d4b2aa
1 changed files with 26 additions and 3 deletions
29
main.py
29
main.py
|
|
@ -1752,10 +1752,17 @@ async def get_combat_stats(character_name: str):
|
||||||
)
|
)
|
||||||
if not row:
|
if not row:
|
||||||
return {"character_name": character_name, "session": None, "lifetime": None}
|
return {"character_name": character_name, "session": None, "lifetime": None}
|
||||||
|
sd = row["stats_data"]
|
||||||
|
if isinstance(sd, str):
|
||||||
|
import json as _json
|
||||||
|
try:
|
||||||
|
sd = _json.loads(sd)
|
||||||
|
except Exception:
|
||||||
|
sd = None
|
||||||
return {
|
return {
|
||||||
"character_name": character_name,
|
"character_name": character_name,
|
||||||
"session": None,
|
"session": None,
|
||||||
"lifetime": row["stats_data"],
|
"lifetime": sd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1776,10 +1783,15 @@ async def get_all_combat_stats():
|
||||||
rows = await database.fetch_all("SELECT character_name, stats_data FROM combat_stats")
|
rows = await database.fetch_all("SELECT character_name, stats_data FROM combat_stats")
|
||||||
for r in rows:
|
for r in rows:
|
||||||
if r["character_name"] not in seen:
|
if r["character_name"] not in seen:
|
||||||
|
sd = r["stats_data"]
|
||||||
|
if isinstance(sd, str):
|
||||||
|
import json as _json
|
||||||
|
try: sd = _json.loads(sd)
|
||||||
|
except Exception: sd = None
|
||||||
results.append({
|
results.append({
|
||||||
"character_name": r["character_name"],
|
"character_name": r["character_name"],
|
||||||
"session": None,
|
"session": None,
|
||||||
"lifetime": r["stats_data"],
|
"lifetime": sd,
|
||||||
})
|
})
|
||||||
results.sort(key=lambda x: x["character_name"])
|
results.sort(key=lambda x: x["character_name"])
|
||||||
return {"stats": results}
|
return {"stats": results}
|
||||||
|
|
@ -3028,7 +3040,18 @@ async def ws_receive_snapshots(
|
||||||
"SELECT stats_data FROM combat_stats WHERE character_name = :n",
|
"SELECT stats_data FROM combat_stats WHERE character_name = :n",
|
||||||
{"n": char},
|
{"n": char},
|
||||||
)
|
)
|
||||||
_combat_lifetime_cache[char] = row["stats_data"] if row else {}
|
if row and row["stats_data"]:
|
||||||
|
sd = row["stats_data"]
|
||||||
|
# DB may return JSON as string — parse if needed
|
||||||
|
if isinstance(sd, str):
|
||||||
|
import json as _json
|
||||||
|
try:
|
||||||
|
sd = _json.loads(sd)
|
||||||
|
except Exception:
|
||||||
|
sd = {}
|
||||||
|
_combat_lifetime_cache[char] = sd
|
||||||
|
else:
|
||||||
|
_combat_lifetime_cache[char] = {}
|
||||||
|
|
||||||
lifetime = _combat_merge_into_lifetime(
|
lifetime = _combat_merge_into_lifetime(
|
||||||
_combat_lifetime_cache[char], delta
|
_combat_lifetime_cache[char], delta
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue