Globale Orphan-Bereinigung: /api/purge-all-orphans + UI-Button
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
37
app.py
37
app.py
@@ -1304,6 +1304,43 @@ def purge_orphan_junctions(obj_id: str):
|
||||
return jsonify({"ok": True, "orphans_removed": removed})
|
||||
|
||||
|
||||
@app.route("/api/purge-all-orphans", methods=["POST"])
|
||||
def purge_all_orphans():
|
||||
"""
|
||||
Bereinigt verwaiste Junction-Einträge für ALLE Objekte auf einmal.
|
||||
Lädt alle Junction-Zeilen und prüft, ob das referenzierte Item noch existiert.
|
||||
"""
|
||||
token = request.headers.get("Authorization", "")
|
||||
removed = 0
|
||||
|
||||
for junc_col, fk_field, item_col in [
|
||||
("questions_objects", "questions_id", "questions"),
|
||||
("words_objects", "words_id", "words"),
|
||||
]:
|
||||
junc_data, _ = _directus("GET",
|
||||
f"/items/{junc_col}?fields=id,{fk_field}&limit=10000", token)
|
||||
rows = junc_data.get("data") or []
|
||||
|
||||
# collect all unique FK values
|
||||
fk_ids = list({row[fk_field] for row in rows if row.get(fk_field)})
|
||||
if not fk_ids:
|
||||
continue
|
||||
|
||||
# fetch which IDs still exist in one bulk call
|
||||
ids_param = ",".join(fk_ids)
|
||||
existing_data, _ = _directus("GET",
|
||||
f"/items/{item_col}?filter[id][_in]={ids_param}&fields=id&limit=10000", token)
|
||||
existing_ids = {e["id"] for e in (existing_data.get("data") or [])}
|
||||
|
||||
orphan_junc_ids = [row["id"] for row in rows
|
||||
if row.get(fk_field) and row[fk_field] not in existing_ids]
|
||||
if orphan_junc_ids:
|
||||
_directus("DELETE", f"/items/{junc_col}", token, orphan_junc_ids)
|
||||
removed += len(orphan_junc_ids)
|
||||
|
||||
return jsonify({"ok": True, "orphans_removed": removed})
|
||||
|
||||
|
||||
@app.route("/api/fix-distractor-field", methods=["POST"])
|
||||
def fix_distractor_field():
|
||||
"""Setzt special=m2m auf questions.distractor_words (einmalig)."""
|
||||
|
||||
Reference in New Issue
Block a user