|
|
@@ -187,7 +187,7 @@ async def person_import_form(request: Request):
|
|
|
|
|
|
@router.post("/dashboard/persons/import", response_class=HTMLResponse)
|
|
|
async def person_import_submit(request: Request):
|
|
|
- import json as json_mod
|
|
|
+ import json as json_mod, asyncio
|
|
|
try:
|
|
|
form = await request.form()
|
|
|
file = form.get("import_file")
|
|
|
@@ -211,20 +211,29 @@ async def person_import_submit(request: Request):
|
|
|
if not name or not bdt or lat is None or lon is None:
|
|
|
errors.append(f"Row {i+1}: missing required fields")
|
|
|
continue
|
|
|
- await storage.add_person(
|
|
|
- name=name, birth_datetime=bdt,
|
|
|
- latitude=float(lat), longitude=float(lon),
|
|
|
- elevation=float(entry.get("elevation", 0) or 0),
|
|
|
- nickname=entry.get("nickname") or None,
|
|
|
- birthplace=entry.get("birthplace") or None,
|
|
|
- alive=bool(entry.get("alive", True)),
|
|
|
- private=bool(entry.get("private", False)),
|
|
|
- gender=entry.get("gender") or None,
|
|
|
- description=entry.get("description") or None,
|
|
|
- notes=entry.get("notes") or None,
|
|
|
- tz=entry.get("timezone") or None,
|
|
|
- birth_time_known=bool(entry.get("birth_time_known", True)),
|
|
|
- )
|
|
|
+ # Retry up to 3 times on locked database
|
|
|
+ for attempt in range(3):
|
|
|
+ try:
|
|
|
+ await storage.add_person(
|
|
|
+ name=name, birth_datetime=bdt,
|
|
|
+ latitude=float(lat), longitude=float(lon),
|
|
|
+ elevation=float(entry.get("elevation", 0) or 0),
|
|
|
+ nickname=entry.get("nickname") or None,
|
|
|
+ birthplace=entry.get("birthplace") or None,
|
|
|
+ alive=bool(entry.get("alive", True)),
|
|
|
+ private=bool(entry.get("private", False)),
|
|
|
+ gender=entry.get("gender") or None,
|
|
|
+ description=entry.get("description") or None,
|
|
|
+ notes=entry.get("notes") or None,
|
|
|
+ tz=entry.get("timezone") or None,
|
|
|
+ birth_time_known=bool(entry.get("birth_time_known", True)),
|
|
|
+ )
|
|
|
+ break
|
|
|
+ except Exception as inner:
|
|
|
+ if "locked" in str(inner).lower() and attempt < 2:
|
|
|
+ await asyncio.sleep(0.5 * (attempt + 1))
|
|
|
+ continue
|
|
|
+ raise
|
|
|
imported += 1
|
|
|
except Exception as e:
|
|
|
errors.append(f"Row {i+1}: {e}")
|