From 2d7e144a210331d1b1f79571d86cf18d075b5d64 Mon Sep 17 00:00:00 2001 From: AutonetSellCar Deploy Date: Sat, 3 Jan 2026 20:30:06 +0900 Subject: [PATCH] Fix duplicate key error in translations auto-extract MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add tracking set to prevent duplicate entries within same batch - Refactor to use helper function for consistent duplicate checking 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- backend/app/api/translations.py | 174 +++++++++++++++----------------- 1 file changed, 84 insertions(+), 90 deletions(-) diff --git a/backend/app/api/translations.py b/backend/app/api/translations.py index d051efa..dba42a1 100644 --- a/backend/app/api/translations.py +++ b/backend/app/api/translations.py @@ -466,128 +466,122 @@ def auto_extract_terms(db: Session = Depends(get_db)): from ..models import Car, CarMaker, CarModel added_count = 0 + # Track already added entries in this batch to avoid duplicates + added_keys = set() + + def add_translation(source_text: str, category: str, text_en: str, text_mn: str, text_ru: str): + nonlocal added_count + key = (source_text, category) + if key in added_keys: + return # Skip duplicate in same batch + + existing = db.query(Translation).filter( + Translation.source_text == source_text, + Translation.category == category + ).first() + if not existing: + trans = Translation( + source_text=source_text, + category=category, + text_en=text_en, + text_mn=text_mn, + text_ru=text_ru + ) + db.add(trans) + added_keys.add(key) + added_count += 1 # Extract makers makers = db.query(CarMaker).all() for maker in makers: - existing = db.query(Translation).filter( - Translation.source_text == maker.name, - Translation.category == "maker" - ).first() - if not existing: + if maker.name: defaults = get_default_translation(maker.name, "maker") - trans = Translation( - source_text=maker.name, - category="maker", - text_en=defaults.get("en") or maker.name_en or maker.name, - text_mn=defaults.get("mn") or maker.name, - text_ru=defaults.get("ru") or maker.name + add_translation( + maker.name, + "maker", + defaults.get("en") or maker.name_en or maker.name, + defaults.get("mn") or maker.name, + defaults.get("ru") or maker.name ) - db.add(trans) - added_count += 1 # Extract models models = db.query(CarModel).all() for model in models: - existing = db.query(Translation).filter( - Translation.source_text == model.name, - Translation.category == "model" - ).first() - if not existing: - # Models usually keep their original names (Sonata, K5, etc.) - trans = Translation( - source_text=model.name, - category="model", - text_en=model.name_en or model.name, - text_mn=model.name_en or model.name, - text_ru=model.name_en or model.name + if model.name: + defaults = get_default_translation(model.name, "model") + add_translation( + model.name, + "model", + defaults.get("en") or model.name_en or model.name, + defaults.get("mn") or model.name_en or model.name, + defaults.get("ru") or model.name_en or model.name ) - db.add(trans) - added_count += 1 # Extract unique fuels fuels = db.query(Car.fuel).distinct().filter(Car.fuel.isnot(None)).all() for (fuel,) in fuels: if fuel: - existing = db.query(Translation).filter( - Translation.source_text == fuel, - Translation.category == "fuel" - ).first() - if not existing: - defaults = get_default_translation(fuel, "fuel") - trans = Translation( - source_text=fuel, - category="fuel", - text_en=defaults.get("en") or fuel, - text_mn=defaults.get("mn") or fuel, - text_ru=defaults.get("ru") or fuel - ) - db.add(trans) - added_count += 1 + defaults = get_default_translation(fuel, "fuel") + add_translation( + fuel, + "fuel", + defaults.get("en") or fuel, + defaults.get("mn") or fuel, + defaults.get("ru") or fuel + ) # Extract unique transmissions transmissions = db.query(Car.transmission).distinct().filter(Car.transmission.isnot(None)).all() for (trans_type,) in transmissions: if trans_type: - existing = db.query(Translation).filter( - Translation.source_text == trans_type, - Translation.category == "transmission" - ).first() - if not existing: - defaults = get_default_translation(trans_type, "transmission") - trans = Translation( - source_text=trans_type, - category="transmission", - text_en=defaults.get("en") or trans_type, - text_mn=defaults.get("mn") or trans_type, - text_ru=defaults.get("ru") or trans_type - ) - db.add(trans) - added_count += 1 + defaults = get_default_translation(trans_type, "transmission") + add_translation( + trans_type, + "transmission", + defaults.get("en") or trans_type, + defaults.get("mn") or trans_type, + defaults.get("ru") or trans_type + ) # Extract unique colors colors = db.query(Car.color).distinct().filter(Car.color.isnot(None)).all() for (color,) in colors: if color: - existing = db.query(Translation).filter( - Translation.source_text == color, - Translation.category == "color" - ).first() - if not existing: - defaults = get_default_translation(color, "color") - trans = Translation( - source_text=color, - category="color", - text_en=defaults.get("en") or color, - text_mn=defaults.get("mn") or color, - text_ru=defaults.get("ru") or color - ) - db.add(trans) - added_count += 1 + defaults = get_default_translation(color, "color") + add_translation( + color, + "color", + defaults.get("en") or color, + defaults.get("mn") or color, + defaults.get("ru") or color + ) # Extract unique car_names and auto-translate car_names = db.query(Car.car_name).distinct().filter(Car.car_name.isnot(None)).all() for (car_name,) in car_names: if car_name: - existing = db.query(Translation).filter( - Translation.source_text == car_name, - Translation.category == "car_name" - ).first() - if not existing: - # Auto-translate car name by translating each component - translated_en = translate_car_name(car_name, "en", db) - translated_mn = translate_car_name(car_name, "mn", db) - translated_ru = translate_car_name(car_name, "ru", db) + key = (car_name, "car_name") + if key not in added_keys: + existing = db.query(Translation).filter( + Translation.source_text == car_name, + Translation.category == "car_name" + ).first() + if not existing: + # Auto-translate car name by translating each component + translated_en = translate_car_name(car_name, "en", db) + translated_mn = translate_car_name(car_name, "mn", db) + translated_ru = translate_car_name(car_name, "ru", db) - trans = Translation( - source_text=car_name, - category="car_name", - text_en=translated_en, - text_mn=translated_mn, - text_ru=translated_ru - ) - db.add(trans) - added_count += 1 + trans = Translation( + source_text=car_name, + category="car_name", + text_en=translated_en, + text_mn=translated_mn, + text_ru=translated_ru + ) + db.add(trans) + added_keys.add(key) + added_count += 1 db.commit()