diff --git a/backend/csv_parser/executor.py b/backend/csv_parser/executor.py index f8025c1..13631af 100644 --- a/backend/csv_parser/executor.py +++ b/backend/csv_parser/executor.py @@ -872,13 +872,14 @@ def _import_activity( dist = _sf_act(mapped.get("distance_km")) wtype = str(activity_type).strip() - training_type_id, training_category, training_subcategory = _resolve_training_type_for_activity( - cur, wtype, profile_id - ) - iso = date_d.isoformat() + # Pro Zeile: bei SQL-Fehler sonst „current transaction is aborted“ bis Xact-Ende. + cur.execute("SAVEPOINT csv_activity_row") try: + training_type_id, training_category, training_subcategory = _resolve_training_type_for_activity( + cur, wtype, profile_id + ) cur.execute( """ SELECT id FROM activity_log @@ -986,7 +987,12 @@ def _import_activity( _evaluate_and_save_activity(cur, aid, activity_dict, training_type_id, profile_id) except Exception as eval_err: logger.warning("[csv activity] Auto-Eval fehlgeschlagen: %s", eval_err) + cur.execute("RELEASE SAVEPOINT csv_activity_row") except Exception as e: + try: + cur.execute("ROLLBACK TO SAVEPOINT csv_activity_row") + except Exception: + pass error_details.append({"row": rows_total, "error": str(e)}) return {