fix: use psycopg2 placeholders (%s) not PostgreSQL ($N)
All checks were successful
Deploy Development / deploy (push) Successful in 51s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s

Bug 1 Final Fix:
- Changed all placeholders from $1, $2, $3 to %s
- psycopg2 expects Python-style %s, converts to $N internally
- Using $N directly causes 'there is no parameter $1' error
- Removed param_idx counter (not needed with %s)

Root cause: Mixing PostgreSQL native syntax with psycopg2 driver
This is THE fix that will finally work!
This commit is contained in:
Lars 2026-03-27 22:14:28 +01:00
parent e4a2b63a48
commit 448f6ad4f4

View File

@ -109,63 +109,54 @@ def create_or_update_baseline(
# Always include profile_id and date
param_values.append(pid)
param_values.append(entry.date)
param_idx = 3 # Next parameter starts at $3
if entry.resting_hr is not None:
insert_cols.append("resting_hr")
insert_placeholders.append(f"${param_idx}")
update_fields.append(f"resting_hr = EXCLUDED.resting_hr")
insert_placeholders.append("%s")
update_fields.append("resting_hr = EXCLUDED.resting_hr")
param_values.append(entry.resting_hr)
param_idx += 1
if entry.hrv is not None:
insert_cols.append("hrv")
insert_placeholders.append(f"${param_idx}")
update_fields.append(f"hrv = EXCLUDED.hrv")
insert_placeholders.append("%s")
update_fields.append("hrv = EXCLUDED.hrv")
param_values.append(entry.hrv)
param_idx += 1
if entry.vo2_max is not None:
insert_cols.append("vo2_max")
insert_placeholders.append(f"${param_idx}")
update_fields.append(f"vo2_max = EXCLUDED.vo2_max")
insert_placeholders.append("%s")
update_fields.append("vo2_max = EXCLUDED.vo2_max")
param_values.append(entry.vo2_max)
param_idx += 1
if entry.spo2 is not None:
insert_cols.append("spo2")
insert_placeholders.append(f"${param_idx}")
update_fields.append(f"spo2 = EXCLUDED.spo2")
insert_placeholders.append("%s")
update_fields.append("spo2 = EXCLUDED.spo2")
param_values.append(entry.spo2)
param_idx += 1
if entry.respiratory_rate is not None:
insert_cols.append("respiratory_rate")
insert_placeholders.append(f"${param_idx}")
update_fields.append(f"respiratory_rate = EXCLUDED.respiratory_rate")
insert_placeholders.append("%s")
update_fields.append("respiratory_rate = EXCLUDED.respiratory_rate")
param_values.append(entry.respiratory_rate)
param_idx += 1
if entry.body_temperature is not None:
insert_cols.append("body_temperature")
insert_placeholders.append(f"${param_idx}")
update_fields.append(f"body_temperature = EXCLUDED.body_temperature")
insert_placeholders.append("%s")
update_fields.append("body_temperature = EXCLUDED.body_temperature")
param_values.append(entry.body_temperature)
param_idx += 1
if entry.resting_metabolic_rate is not None:
insert_cols.append("resting_metabolic_rate")
insert_placeholders.append(f"${param_idx}")
update_fields.append(f"resting_metabolic_rate = EXCLUDED.resting_metabolic_rate")
insert_placeholders.append("%s")
update_fields.append("resting_metabolic_rate = EXCLUDED.resting_metabolic_rate")
param_values.append(entry.resting_metabolic_rate)
param_idx += 1
if entry.note:
insert_cols.append("note")
insert_placeholders.append(f"${param_idx}")
update_fields.append(f"note = EXCLUDED.note")
insert_placeholders.append("%s")
update_fields.append("note = EXCLUDED.note")
param_values.append(entry.note)
param_idx += 1
# At least one field must be provided
if not insert_cols:
@ -175,8 +166,9 @@ def create_or_update_baseline(
cur = get_cursor(conn)
# Build complete column list and placeholder list
# IMPORTANT: psycopg2 uses %s placeholders, NOT $1/$2/$3
all_cols = f"profile_id, date, {', '.join(insert_cols)}"
all_placeholders = f"$1, $2, {', '.join(insert_placeholders)}"
all_placeholders = f"%s, %s, {', '.join(insert_placeholders)}"
query = f"""
INSERT INTO vitals_baseline ({all_cols})