ifixkart-backend/backfill_media.py

112 lines
4.1 KiB
Python

import pymysql
import re
import ulid
def canonicalize_media_key(raw_key):
if not raw_key:
return None
s = str(raw_key).strip().lower()
s = re.sub(r'[\s_/\\]+', '-', s)
s = re.sub(r'-+', '-', s)
s = s.strip('-')
return s if s else None
conn = pymysql.connect(unix_socket='/var/run/mysqld/mysqld.sock', user='root', password='', database='ifixkartecommerce', autocommit=False)
cur = conn.cursor()
print("=== Fetching indexed media_groups and media_assets ===")
cur.execute("SELECT id, media_key FROM media_groups")
mg_rows = cur.fetchall()
media_group_map = {}
for mg_id, media_key in mg_rows:
cur.execute("SELECT cdn_url FROM media_library WHERE media_group_id = %s ORDER BY created_at ASC", (mg_id,))
asset_urls = [r[0] for r in cur.fetchall()]
if asset_urls:
media_group_map[media_key] = asset_urls
print(f"Indexed media groups with valid assets: {len(media_group_map)}")
print("=== Fetching all products with Brand and Category ===")
cur.execute("""
SELECT p.product_id, p.name, p.slug, b.slug as brand_slug, c.slug as category_slug
FROM products p
LEFT JOIN brands b ON p.brand_id = b.brand_id
LEFT JOIN categories c ON p.category_id = c.category_id
""")
products = cur.fetchall()
prod_linked_count = 0
var_linked_count = 0
for product_id, name, slug, brand_slug, category_slug in products:
# Fetch variants for this product
cur.execute("SELECT variant_id FROM product_variants WHERE product_id = %s", (product_id,))
variants = [r[0] for r in cur.fetchall()]
prod_matched_urls = []
for v_id in variants:
# Fetch Color attribute for variant
cur.execute("""
SELECT va.attribute_value
FROM variant_attributes va
JOIN attribute_types at ON va.attribute_id = at.attribute_id
WHERE va.variant_id = %s AND (at.code = 'color' OR at.name = 'Color')
LIMIT 1
""", (v_id,))
color_row = cur.fetchone()
color_val = color_row[0] if color_row else ""
# Candidates
candidates = []
if brand_slug and category_slug and color_val:
color_slug = canonicalize_media_key(color_val)
candidates.append(f"{brand_slug}-{category_slug}-{color_slug}")
candidates.append(f"{brand_slug}-{category_slug}")
if brand_slug and category_slug:
candidates.append(f"{brand_slug}-{category_slug}")
candidates.append(canonicalize_media_key(slug))
candidates.append(canonicalize_media_key(name))
matched_urls = None
for k in candidates:
if k and k in media_group_map:
matched_urls = media_group_map[k]
break
if not matched_urls and brand_slug and category_slug:
prefix = f"{brand_slug}-{category_slug}"
for k, urls in media_group_map.items():
if k.startswith(prefix):
matched_urls = urls
break
if matched_urls:
cur.execute("DELETE FROM variant_images WHERE variant_id = %s", (v_id,))
for idx, url in enumerate(matched_urls):
vi_id = str(ulid.ULID())
cur.execute(
"INSERT INTO variant_images (image_id, variant_id, image_url, sort_order, is_primary) VALUES (%s, %s, %s, %s, %s)",
(vi_id, v_id, url, idx, idx == 0)
)
var_linked_count += 1
if not prod_matched_urls:
prod_matched_urls = matched_urls
if prod_matched_urls:
cur.execute("DELETE FROM product_images WHERE product_id = %s", (product_id,))
for idx, url in enumerate(prod_matched_urls):
pi_id = str(ulid.ULID())
cur.execute(
"INSERT INTO product_images (image_id, product_id, image_url, alt_text, sort_order, is_banner) VALUES (%s, %s, %s, %s, %s, %s)",
(pi_id, product_id, url, f"{name} Image {idx+1}", idx, idx == 0)
)
prod_linked_count += 1
conn.commit()
print(f"=== Backfill Complete! ===")
print(f"Linked images to {prod_linked_count} products and {var_linked_count} variants.")
conn.close()