94 lines
3.4 KiB
Python
94 lines
3.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Backfill PostgreSQL brand tables with `barcode` and `barcode_type` from seed catalogs.
|
|
This ensures existing products with barcode details in seed files or DB rows are populated and served to the API and UI.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import logging
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
|
|
|
from app.services.vector_store import _connect, list_available_brands, _sanitize_name, resolve_parent_brand, ensure_brand_schema
|
|
|
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
|
|
logger = logging.getLogger(__name__)
|
|
|
|
SEED_DIR = Path(__file__).resolve().parents[1] / "data" / "seed_catalogs"
|
|
|
|
|
|
def backfill_barcodes() -> None:
|
|
conn = _connect()
|
|
if not conn:
|
|
logger.error("Could not connect to PostgreSQL database.")
|
|
return
|
|
|
|
brands = list_available_brands()
|
|
logger.info("Ensuring schema for %d brand(s)...", len(brands))
|
|
for brand in brands:
|
|
ensure_brand_schema(brand)
|
|
|
|
seed_files = sorted(SEED_DIR.glob("*.json")) if SEED_DIR.exists() else []
|
|
logger.info("Found %d seed file(s) in %s", len(seed_files), SEED_DIR)
|
|
|
|
updated_count = 0
|
|
with conn.cursor() as cur:
|
|
for seed_file in seed_files:
|
|
try:
|
|
data = json.loads(seed_file.read_text(encoding="utf-8-sig"))
|
|
except Exception as e:
|
|
logger.warning("Could not read seed file %s: %s", seed_file.name, e)
|
|
continue
|
|
|
|
products = data.get("products", [])
|
|
brand = data.get("brand") or (products[0].get("brand_name") if products else None)
|
|
if not brand or not products:
|
|
continue
|
|
|
|
table_name = f"brand_{_sanitize_name(resolve_parent_brand(brand))}"
|
|
|
|
for p in products:
|
|
image_id = p.get("image_id") or p.get("sku") or ""
|
|
product_name = p.get("product_name") or p.get("title") or ""
|
|
barcode = str(p.get("barcode") or p.get("Barcode") or "").strip() or None
|
|
barcode_type = str(p.get("barcode_type") or p.get("Barcode_Type") or "").strip() or None
|
|
|
|
if not barcode and not barcode_type:
|
|
continue
|
|
|
|
if image_id:
|
|
cur.execute(
|
|
f"""
|
|
UPDATE {table_name}
|
|
SET barcode = COALESCE(%s, barcode),
|
|
barcode_type = COALESCE(%s, barcode_type)
|
|
WHERE image_id = %s
|
|
""",
|
|
(barcode, barcode_type, image_id)
|
|
)
|
|
if cur.rowcount > 0:
|
|
updated_count += cur.rowcount
|
|
elif product_name:
|
|
cur.execute(
|
|
f"""
|
|
UPDATE {table_name}
|
|
SET barcode = COALESCE(%s, barcode),
|
|
barcode_type = COALESCE(%s, barcode_type)
|
|
WHERE product_name = %s
|
|
""",
|
|
(barcode, barcode_type, product_name)
|
|
)
|
|
if cur.rowcount > 0:
|
|
updated_count += cur.rowcount
|
|
|
|
conn.commit()
|
|
conn.close()
|
|
logger.info("🎉 Barcode backfill complete! Updated %d product row(s).", updated_count)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
backfill_barcodes()
|