hisham-cmd commited on
Commit
ec31d74
·
verified ·
1 Parent(s): f8db90b

Upload app/api/seed.py

Browse files
Files changed (1) hide show
  1. app/api/seed.py +52 -14
app/api/seed.py CHANGED
@@ -1,5 +1,6 @@
1
  from fastapi import APIRouter, Depends
2
  from sqlalchemy.orm import Session
 
3
  import json
4
  import random
5
  import os
@@ -11,6 +12,7 @@ from app.models.cart import Coupon
11
  from app.models.user import User, UserRole, AuthProvider
12
  from app.core.security import hash_password
13
  from app.schemas.auth import AuthResponse
 
14
 
15
  router = APIRouter(prefix="/seed", tags=["Seed Data"])
16
 
@@ -53,11 +55,29 @@ def get_image_url(parent_category: str, product_name: str, index: int):
53
  return f"https://source.unsplash.com/featured/800x1000?{brand_keyword},{parent_category}&sig={unique_sig}"
54
 
55
  @router.post("", response_model=AuthResponse)
56
- async def seed_database(db: Session = Depends(get_db)):
57
- """Populate database with proper product data from json dump and an admin user."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  # Always ensure admin user exists
59
- existing_admin = db.query(User).filter(User.email == "admin@vortex.com").first()
60
- if not existing_admin:
 
61
  admin_user = User(
62
  name="Admin",
63
  email="admin@vortex.com",
@@ -68,14 +88,15 @@ async def seed_database(db: Session = Depends(get_db)):
68
  db.add(admin_user)
69
  db.commit()
70
 
71
- # Check if products are already seeded
72
- existing = db.query(Category).count()
73
- if existing > 0:
74
- return AuthResponse(
75
- isSuccess=True,
76
- value={"message": "Database already has data. Admin user ensured."},
77
- statusCode=200,
78
- )
 
79
 
80
  json_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "products_dump.json")
81
  if not os.path.exists(json_path):
@@ -174,6 +195,22 @@ async def seed_database(db: Session = Depends(get_db)):
174
  if inserted_count >= 500: # Maintain a safe limit for demonstration
175
  break
176
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  # Seed Coupons
178
  DEMO_COUPONS = [
179
  {"code": "WELCOME10", "discount_percent": 10.0, "is_active": True},
@@ -190,9 +227,10 @@ async def seed_database(db: Session = Depends(get_db)):
190
  return AuthResponse(
191
  isSuccess=True,
192
  value={
193
- "message": "Database seeded successfully",
194
  "categories_count": db.query(Category).count(),
195
- "products_count": inserted_count,
 
196
  "coupons_count": len(DEMO_COUPONS),
197
  },
198
  statusCode=201,
 
1
  from fastapi import APIRouter, Depends
2
  from sqlalchemy.orm import Session
3
+ from sqlalchemy import text
4
  import json
5
  import random
6
  import os
 
12
  from app.models.user import User, UserRole, AuthProvider
13
  from app.core.security import hash_password
14
  from app.schemas.auth import AuthResponse
15
+ from app.services.external_catalog import ExternalCatalogService
16
 
17
  router = APIRouter(prefix="/seed", tags=["Seed Data"])
18
 
 
55
  return f"https://source.unsplash.com/featured/800x1000?{brand_keyword},{parent_category}&sig={unique_sig}"
56
 
57
  @router.post("", response_model=AuthResponse)
58
+ async def seed_database(clear: bool = False, db: Session = Depends(get_db)):
59
+ """Populate database with proper product data, optionally clearing existing data first."""
60
+ if clear:
61
+ # Clear existing data using raw SQL to avoid materialization errors if enums changed
62
+ db.execute(text("DELETE FROM product_images"))
63
+ db.execute(text("DELETE FROM products"))
64
+ db.execute(text("DELETE FROM categories"))
65
+ db.execute(text("DELETE FROM coupons"))
66
+ # Optional: clear users if you want a fresh start, or just fix the admin
67
+ db.execute(text("UPDATE users SET role = 'ADMIN' WHERE role = 'admin'")) # Fix legacy enums
68
+
69
+ # Patch schema: add specs column if missing (SQLite doesn't support IF NOT EXISTS in ALTER)
70
+ try:
71
+ db.execute(text("ALTER TABLE products ADD COLUMN specs JSON"))
72
+ except Exception:
73
+ pass # Already exists or other issue
74
+
75
+ db.commit()
76
+
77
  # Always ensure admin user exists
78
+ # Use raw SQL to check for admin to avoid LookupError if data is inconsistent
79
+ admin_exists = db.execute(text("SELECT id FROM users WHERE email = 'admin@vortex.com'")).fetchone()
80
+ if not admin_exists:
81
  admin_user = User(
82
  name="Admin",
83
  email="admin@vortex.com",
 
88
  db.add(admin_user)
89
  db.commit()
90
 
91
+ # Check if products are already seeded (Skip if clearing)
92
+ if not clear:
93
+ existing = db.query(Category).count()
94
+ if existing > 0:
95
+ return AuthResponse(
96
+ isSuccess=True,
97
+ value={"message": "Database already has data. Admin user ensured."},
98
+ statusCode=200,
99
+ )
100
 
101
  json_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "products_dump.json")
102
  if not os.path.exists(json_path):
 
195
  if inserted_count >= 500: # Maintain a safe limit for demonstration
196
  break
197
 
198
+ # 4. Enrich with Real Discovered Products
199
+ ext_service = ExternalCatalogService(db)
200
+ discovered_data = []
201
+ if os.path.exists(ext_service.discovery_file):
202
+ with open(ext_service.discovery_file, "r", encoding="utf-8") as f:
203
+ discovered_data = json.load(f)
204
+
205
+ real_count = 0
206
+ for ext_item in discovered_data:
207
+ # Avoid duplicates by name
208
+ if ext_item.get("name_ar") in used_names or ext_item.get("title") in used_names:
209
+ continue
210
+ await ext_service.create_product_from_external(ext_item)
211
+ used_names.add(ext_item.get("name_ar") or ext_item.get("title"))
212
+ real_count += 1
213
+
214
  # Seed Coupons
215
  DEMO_COUPONS = [
216
  {"code": "WELCOME10", "discount_percent": 10.0, "is_active": True},
 
227
  return AuthResponse(
228
  isSuccess=True,
229
  value={
230
+ "message": "Database seeded with real products successfully",
231
  "categories_count": db.query(Category).count(),
232
+ "dummy_products": inserted_count,
233
+ "real_products": real_count,
234
  "coupons_count": len(DEMO_COUPONS),
235
  },
236
  statusCode=201,