feat(csv-import): Implement SAVEPOINT handling for vitals baseline import
Some checks failed
Deploy Development / deploy (push) Successful in 55s
Build Test / pytest-backend (push) Failing after 1s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 17s

- Updated the CSV import logic to include SAVEPOINT management, allowing for better error handling during the vitals baseline import process.
- Enhanced the SQL migration script to drop existing CHECK constraints related to the 'source' field, ensuring compatibility with the new universal CSV import.
- Incremented DB_SCHEMA_VERSION to "20260409c" to reflect these changes and improve the import process reliability.
This commit is contained in:
Lars 2026-04-10 16:11:08 +02:00
parent e60976e1cc
commit 5a0c71dd90
5 changed files with 52 additions and 4 deletions

View File

@ -588,6 +588,9 @@ def _import_vitals_baseline(
continue
iso = d.isoformat()
try:
# Ohne SAVEPOINT: erster fehlgeschlagener INSERT setzt die Xact auf „aborted“,
# alle folgenden Queries + commit() schlagen fehl → generischer 500.
cur.execute("SAVEPOINT vitals_csv_row")
cur.execute(
"""
INSERT INTO vitals_baseline (
@ -619,8 +622,15 @@ def _import_vitals_baseline(
updated += 1
if result.get("id"):
affected_ids["vitals_baseline"].append(str(result["id"]))
cur.execute("RELEASE SAVEPOINT vitals_csv_row")
except Exception as e:
error_details.append({"row": rows_total, "error": str(e)})
try:
cur.execute("ROLLBACK TO SAVEPOINT vitals_csv_row")
except Exception:
pass
error_details.append(
{"row": rows_total, "error": str(e), "context": "vitals_baseline upsert"},
)
return {
"rows_total": rows_total,

View File

@ -1,5 +1,22 @@
-- Universal-CSV-Import schreibt source = 'csv'; bisherige CHECK erlaubte das nicht → 500 beim Import.
ALTER TABLE vitals_baseline DROP CONSTRAINT IF EXISTS vitals_baseline_source_check;
-- Universal-CSV-Import setzt source = 'csv'. Alte CHECK-Constraints kennen das nicht.
-- Namen können je nach PG-Version abweichen → alle passenden CHECK Constraints zu source droppen.
DO $$
DECLARE
r RECORD;
BEGIN
FOR r IN
SELECT c.conname
FROM pg_constraint c
JOIN pg_class t ON c.conrelid = t.oid
WHERE t.relname = 'vitals_baseline'
AND c.contype = 'c'
AND pg_get_constraintdef(c.oid) ILIKE '%source%'
AND pg_get_constraintdef(c.oid) ILIKE '%IN %'
LOOP
EXECUTE format('ALTER TABLE vitals_baseline DROP CONSTRAINT %I', r.conname);
END LOOP;
END $$;
ALTER TABLE vitals_baseline ADD CONSTRAINT vitals_baseline_source_check
CHECK (source IN ('manual', 'apple_health', 'garmin', 'withings', 'csv'));

View File

@ -0,0 +1,20 @@
-- Idempotent: erneute Bereinigung der source-CHECK, falls 048 zuvor nicht griff oder nur teilweise lief.
DO $$
DECLARE
r RECORD;
BEGIN
FOR r IN
SELECT c.conname
FROM pg_constraint c
JOIN pg_class t ON c.conrelid = t.oid
WHERE t.relname = 'vitals_baseline'
AND c.contype = 'c'
AND pg_get_constraintdef(c.oid) ILIKE '%source%'
AND pg_get_constraintdef(c.oid) ILIKE '%IN %'
LOOP
EXECUTE format('ALTER TABLE vitals_baseline DROP CONSTRAINT %I', r.conname);
END LOOP;
END $$;
ALTER TABLE vitals_baseline ADD CONSTRAINT vitals_baseline_source_check
CHECK (source IN ('manual', 'apple_health', 'garmin', 'withings', 'csv'));

View File

@ -477,6 +477,7 @@ async def csv_import_execute(
m,
)
except Exception as exec_err:
logger.exception("Universal-CSV-Import fehlgeschlagen: %s", exec_err)
cur.execute("ROLLBACK TO SAVEPOINT csv_import_exec")
cur.execute(
"""

View File

@ -9,7 +9,7 @@ Semantic Versioning: MAJOR.MINOR.PATCH
APP_VERSION = "0.9p"
BUILD_DATE = "2026-04-09"
DB_SCHEMA_VERSION = "20260409b" # u. a. 048 vitals_baseline.source csv
DB_SCHEMA_VERSION = "20260409c" # 048/049 vitals_baseline.source csv + SAVEPOINT Import
MODULE_VERSIONS = {
"auth": "1.2.0",