App / scripts /seed_postgres.py
Devang Makwana
Update HomeScreen Image
2c1fb1d
Raw
History Blame Contribute Delete
42.8 kB
#!/usr/bin/env python3
"""
Gujarat Street-Grid Seed for PostgreSQL
Generates workers + stores across ALL Gujarat cities with dense grid (~800m spacing).
Inserts directly into PostgreSQL using the same schema as the Rust backend.
Usage:
python scripts/seed_postgres.py
"""
import os, sys, json, random, math, hashlib, re
from datetime import datetime, timedelta
from dotenv import load_dotenv
import psycopg2
import psycopg2.extras
load_dotenv(os.path.join(os.path.dirname(__file__), '..', '.env'))
DATABASE_URL = os.getenv('DATABASE_URL')
BATCH_SIZE = 500
CLEAR_EXISTING = True
DICE_BEAR = "https://api.dicebear.com/7.x/initials/png?seed=%s&backgroundType=gradientLinear&backgroundRotation=0,360"
LANGUAGES = ["Gujarati", "Hindi", "English"]
CITIES = {
"Ahmedabad": (23.0225, 72.5714, 32, 24, 1.0),
"Surat": (21.1702, 72.8311, 22, 18, 1.0),
"Vadodara": (22.3072, 73.1812, 16, 12, 0.8),
"Rajkot": (22.3039, 70.8022, 14, 10, 0.8),
"Bhavnagar": (21.7645, 72.1519, 12, 10, 0.7),
"Jamnagar": (22.4707, 70.0577, 11, 9, 0.7),
"Junagadh": (21.5222, 70.4579, 9, 8, 0.6),
"Gandhinagar": (23.2156, 72.6369, 8, 6, 0.6),
"Anand": (22.5645, 72.9289, 8, 6, 0.6),
"Nadiad": (22.6916, 72.8617, 7, 6, 0.6),
"Morbi": (22.8245, 70.8337, 7, 6, 0.6),
"Bharuch": (21.7051, 72.9958, 7, 6, 0.6),
"Navsari": (20.9467, 72.9520, 7, 6, 0.6),
"Valsad": (20.6060, 72.9343, 7, 6, 0.6),
"Mehsana": (23.5880, 72.3698, 8, 6, 0.6),
"Palanpur": (24.1710, 72.4381, 7, 5, 0.5),
"Porbandar": (21.6417, 69.6293, 7, 6, 0.5),
"Surendranagar":(22.7270, 71.6487, 7, 5, 0.5),
"Bhuj": (23.2420, 69.6669, 8, 6, 0.5),
"Gandhidham": (23.0853, 70.1194, 7, 5, 0.5),
"Godhra": (22.7780, 73.6148, 6, 5, 0.5),
"Dahod": (22.8450, 74.2600, 6, 5, 0.5),
"Patan": (23.8499, 72.1263, 6, 5, 0.5),
"Himmatnagar": (23.6000, 72.9500, 6, 5, 0.5),
"Veraval": (20.9085, 70.3623, 6, 5, 0.5),
"Amreli": (21.6111, 71.2421, 6, 5, 0.5),
"Botad": (22.1700, 71.6700, 5, 4, 0.5),
"Gondal": (21.9600, 70.8000, 5, 4, 0.5),
"Jetpur": (21.7500, 70.6200, 5, 4, 0.5),
"Kalol": (23.2430, 72.4960, 5, 4, 0.5),
"Kheda": (22.7520, 72.6850, 5, 4, 0.5),
"Sidhpur": (23.9160, 72.3720, 5, 4, 0.5),
"Visnagar": (23.6980, 72.5510, 5, 4, 0.5),
"Unjha": (23.8000, 72.4000, 5, 4, 0.5),
"Deesa": (24.2500, 72.1830, 5, 4, 0.5),
"Dhoraji": (21.7320, 70.4520, 4, 4, 0.5),
"Upleta": (21.7310, 70.2800, 4, 4, 0.5),
"Mahuva": (21.0830, 71.8000, 4, 4, 0.5),
"Palitana": (21.5250, 71.8230, 4, 4, 0.5),
"Modasa": (23.4670, 73.3000, 4, 4, 0.5),
"Vapi": (20.3710, 72.9040, 5, 4, 0.5),
"Vijapur": (23.5670, 72.7500, 4, 4, 0.5),
"Kapadvanj": (23.0200, 73.0700, 4, 4, 0.5),
"Tharad": (24.3900, 71.6200, 4, 4, 0.5),
"Lunavada": (23.1300, 73.6100, 4, 4, 0.5),
"Chhota Udepur":(22.3000, 74.0100, 4, 4, 0.5),
}
CITY_AREAS = {
"Ahmedabad": ["Satellite", "Bopal", "Maninagar", "Navrangpura", "Vastrapur", "Thaltej", "Paldi", "Naranpura", "Gota", "Chandkheda", "Isanpur", "Naroda", "Vejalpur", "Prahlad Nagar", "Bodakdev", "SG Highway", "Science City", "Ranip", "Sabarmati", "Odhav", "Vatva", "Nikol", "Bapunagar", "Gomtipur", "Raipur", "Kankaria", "Ellisbridge", "Shahibaug", "Asarwa", "Nava Vadaj"],
"Surat": ["Adajan", "Vesu", "Piplod", "Katargam", "Varachha", "Udhna", "Athwa", "Dumas", "City Light", "Althan", "Bhatar", "Amroli", "Palanpur Patia", "Sagrampura", "Nanpura", "Rander", "Mota Varachha", "Parvat Patia", "Kapodra", "Umarwada", "Yogi Chowk", "Ghod Dod Road", "Hajira", "Magdalla", "Sachin"],
"Vadodara": ["Alkapuri", "Gotri", "Manjalpur", "Karelibaug", "Akota", "Harni", "Waghodia", "Nizampura", "Sama", "Fatehgunj", "Makarpura", "Subhanpura", "Gorwa", "Dabhoi Road", "Raopura", "Mandal", "Tarsali", "Vasad", "Karjan", "Savli"],
"Rajkot": ["Kalawad Road", "Yagnik Road", "150 Feet Ring Road", "Race Course", "Kotecha Chowk", "Mavdi", "University Road", "Raiya Road", "Amin Marg", "Bedipara", "Gondal Road", "Dhebar Road", "Sadhu Vaswani Road", "Bhaktinagar", "Shapar", "Kuvadava Road", "Nana Mavdi", "Junction Plot", "Sadhuvaswani", "Madhapar", "Gokul", "Kothariya", "Bhavani", "Sanala Road"],
"Bhavnagar": ["Kaliyabid", "Nilambaug", "Krishna Nagar", "Sardarnagar", "Ghogh Circle", "Takhteshwar", "Vidyanagar", "Chitra", "Ratanpara", "Adarsh Nagar", "Shastrinagar", "Malvav", "Kumbharwada"],
"Jamnagar": ["Indira Gandhi Marg", "Darbargadh", "Palanpur", "Udyognagar", "Shanker Tekri", "Gurukul", "Vijay Nagar", "Digvijay Plot", "Vibhapar", "Lakhota", "Airport Road", "Bedis Road"],
"Junagadh": ["Joshipura", "Moti Baug", "MG Road", "Kalwa Chowk", "Zanzarda", "Bhavnath", "Sardar Baug", "Keshod Road", "Kadiya", "Satasi", "Vanthali", "Bhesan"],
"Gandhinagar": ["Sector 1", "Sector 2", "Sector 3", "Sector 4", "Sector 5", "Sector 6", "Sector 7", "Sector 8", "Sector 9", "Sector 10", "Sector 11", "Sector 12", "Sector 13", "Sector 14", "Sector 15", "Sector 16", "Sector 17", "Sector 18", "Sector 19", "Sector 20", "Sector 21", "Sector 22", "Sector 23", "Sector 24", "Sector 25", "Sector 26", "Sector 27", "Sector 28", "Sector 29", "Sector 30", "GIDC", "Infinite City", "Sargasan", "Kudasan", "Randesan", "Pethapur", "Raysan"],
"Anand": ["Vallabh Vidyanagar", "Borsad Road", "Anand Station Road", "Gamdi", "Bakrol", "Chikhodra", "Mogri", "Karamsad", "Vitthal Udyognagar"],
"Nadiad": ["Ghogha Cross Road", "Santram Road", "Mahagujarat Society", "Vadtal Road", "Bhatta", "Shahpur", "Barejadi", "Rameshwar Road", "Marine Lines", "Mahadev Faliya"],
"Morbi": ["Bagdana", "Wankaner Road", "Sanala Road", "Shapur", "Ghanshyam Nagar", "Shastri Nagar", "Tankara Road", "Bharatnagar", "Gundala", "Haripar"],
"Bharuch": ["Zadeshwar", "Ankleshwar", "Panchbhatti", "Station Road", "Vadia", "Netang", "Kosamdi", "Vadia"],
"Navsari": ["Chhapra Road", "Sanskar Society", "Canal Road", "Eru", "Jalalpore", "Vijalpore", "Mohan Nagar", "Dhulia"],
"Valsad": ["Station Road", "Tithal Road", "Halpati Vasahat", "Nana Khajod", "Chharwada", "Atul", "Dharampur", "Umargam"],
"Mehsana": ["Gulabpura", "Highway Road", "Radhanpur Road", "Vishnu Nagar", "Jagudan", "Modhera", "Kheralu", "Vadnagar", "Gojariya", "Jethal"],
"Palanpur": ["Highway Road", "Johari Bazar", "Gunjar", "Mithi Road", "Bhogal", "Ambaji Road", "Kankrej", "Dhanera Road"],
"Porbandar": ["Ghodbunder", "Mistry Plot", "Kutiyana Road", "Bhadrod", "Prabhas Patan", "Madhavpur", "Miyani"],
"Surendranagar": ["Wadhwan", "Chhipdi", "Highway Road", "Lakhtar Road", "Dharangadhra", "Limdi", "Muli Road", "Thangadh", "Halvad"],
"Bhuj": ["Hospital Road", "Madhapar", "Mundra Road", "Bhimasar", "Rapar", "Mirzapur", "Naranpur", "Kukma", "Lakadia", "Kera"],
"Gandhidham": ["Plot 1-380", "Kandla", "Sector 1-15", "Adipur", "Galpadar", "Gandhidham Station", "Shivaji Nagar"],
"Godhra": ["Kalol Road", "Station Road", "Halol Road", "Fatepura", "Dahod Road", "Khanpur", "Timba Road"],
"Dahod": ["Jhalod Road", "Station Road", "Fatehpura", "Chandwada", "Devgadh Baria Road", "Limkheda", "Singvad"],
"Patan": ["Chanasma Road", "Siddhpur Road", "Bhabhar", "Santalpur", "Radhanpur", "Sami", "Harij"],
"Himmatnagar": ["Talod Road", "Prantij", "Station Road", "Khedbrahma Road", "Vijaynagar", "Idar Road", "Vadali", "Bayad"],
"Veraval": ["Somnath", "Patanvav", "Station Road", "Prabhas Patan", "Kodinar", "Jalgaon", "Mul Dwarka"],
"Amreli": ["Baba Road", "Khimmat Nagar", "Chalala Road", "Dhari", "Savar Kundla", "Rajula", "Lathi", "Babra"],
"Botad": ["Ahmedabad Road", "Gadhada", "Station Road", "Rangpur", "Lathidad", "Ranpur", "Barvala"],
"Gondal": ["Rajkot Road", "Jetpur Road", "Station Road", "Nana Mavdi", "Bhakti Nagar", "Dhoraji Road", "Vadia"],
"Jetpur": ["Upleta Road", "Dhoraji Road", "Station Road", "Gadhka", "Chital", "Ventrapur", "Moti Vavdi"],
"Kalol": ["Station Road", "Market Road", "Santram Road", "Nagalpur", "Kadi Road", "Bajwa", "Dharoi Road"],
"Kheda": ["Station Road", "Borsad Road", "Kapadvanj Road", "Guruvaya", "Chhipdi", "Mahalet"],
"Sidhpur": ["Station Road", "Bazar Road", "Junagadh Road", "Ambali", "Galisana", "Bhandu"],
"Visnagar": ["Station Road", "Modhera Road", "Kheralu Road", "Vadnagar Road", "Siddhpur Road", "Kamalpur"],
"Unjha": ["Station Road", "Market Yard", "Siddhpur Road", "Jagudan", "Chanasma", "Khara", "Rampur"],
"Deesa": ["Station Road", "Highway Road", "Palanpur Road", "Dhanera Road", "Abu Road", "Mitha", "Bodana"],
"Dhoraji": ["Station Road", "Jetpur Road", "Upleta Road", "Gondal Road", "Keshod Road", "Kalavad Road"],
"Upleta": ["Station Road", "Dhoraji Road", "Jetpur Road", "Mahuva Road", "Kotharia", "Patanvav"],
"Mahuva": ["Station Road", "Palitana Road", "Talaja Road", "Bhavnagar Road", "Sihor Road", "Ghogha Road"],
"Palitana": ["Station Road", "Bhavnagar Road", "Mahuva Road", "Talaja Road", "Gadhada", "Gariyadhar"],
"Modasa": ["Station Road", "Himmatnagar Road", "Meghraj Road", "Bhadiadar", "Bhiloda", "Bavali"],
"Vapi": ["Station Road", "GIDC", "Daman Road", "Silvassa Road", "Pardi", "Bhilad", "Chharwada"],
"Vijapur": ["Station Road", "Mehsana Road", "Kadi Road", "Visnagar Road", "Palanpur Road", "Kheralu"],
"Kapadvanj": ["Station Road", "Kheda Road", "Modasa Road", "Lunavada", "Manipur", "Salap"],
"Tharad": ["Station Road", "Deesa Road", "Santalpur Road", "Vavi", "Dhanera", "Lakhni"],
"Lunavada": ["Station Road", "Godhra Road", "Modasa Road", "Balasinor", "Santrampur", "Kadana"],
"Chhota Udepur": ["Station Road", "Jetpur Road", "Kawant Road", "Naswadi", "Pavi Jetpur", "Bodeli"],
}
CATEGORIES = {
"plumbing": ["Pipe Repair", "Tap Installation", "Drain Cleaning", "Water Heater Service", "Bathroom Fitting"],
"electrical": ["Wiring Repair", "Fan Installation", "MCB Box Repair", "Light Installation", "Smart Home Setup"],
"cleaning": ["Deep Cleaning", "Kitchen Cleaning", "Office Cleaning", "Sofa & Carpet Cleaning", "Bathroom Scrubbing"],
"carpentry": ["Furniture Repair", "Door Fitting", "Custom Furniture", "Kitchen Cabinet Work", "Wood Polishing"],
"painting": ["Wall Painting", "Texture Finish", "Exterior Painting", "Waterproofing", "Furniture Spray Paint"],
"ac": ["AC Service", "AC Repair", "Gas Refill", "AC Installation", "Duct Cleaning"],
"salon": ["Haircut", "Beard Trim", "Hair Color", "Facial", "Bridal Makeup", "Manicure"],
"vehicle": ["Bike Service", "Car Service", "Tyre Change", "Engine Repair", "Battery Replacement", "Denting & Painting"],
"pest_control": ["Cockroach Treatment", "Mosquito Control", "Termite Treatment", "Bed Bug Treatment", "Rodent Control"],
"packers_movers": ["House Shifting", "Office Relocation", "Loading-Unloading", "Vehicle Transport", "Packing Service"],
"photography": ["Wedding Photography", "Portrait Shoot", "Event Coverage", "Product Photography", "Cinematography"],
"catering": ["Home Catering", "Party Catering", "Wedding Catering", "Snacks Service", "Lunch Delivery Service"],
"laundry": ["Wash & Fold", "Dry Cleaning", "Ironing Service", "Carpet Cleaning", "Curtain Wash"],
"tailoring": ["Custom Stitching", "Alterations", "Designer Wear", "Uniform Stitching", "Leather Work"],
"fitness": ["Personal Training", "Yoga Classes", "Gym Sessions", "Diet Planning", "Zumba Classes"],
"tutoring": ["Home Tuition", "Online Classes", "Subject Tutoring", "Exam Prep", "Language Classes"],
"home_renovation": ["Full Renovation", "Kitchen Remodel", "Bathroom Renovation", "Wall Demolition", "Flooring Work"],
"interior_design": ["Home Interior", "Office Design", "Space Planning", "Furniture Layout", "Lighting Design"],
"appliance_repair": ["Washing Machine Repair", "Fridge Repair", "Microwave Repair", "Water Purifier Service", "Geyser Repair"],
"roofing": ["Waterproofing", "Roof Repair", "Terrace Sealing", "Membrane Installation", "Roof Coating"],
"flooring": ["Tile Installation", "Marble Polishing", "Wood Flooring", "Vinyl Flooring", "Floor Grouting"],
"welding": ["Gate Fabrication", "Railing Work", "Grill Making", "Structure Welding", "Aluminum Work"],
"event_planning": ["Birthday Planning", "Wedding Planning", "Corporate Events", "Decor Service", "Catering Coordination"],
"security": ["CCTV Installation", "Security Guard", "Biometric System", "Alarm Installation", "Intercom Setup"],
"gardening": ["Lawn Mowing", "Garden Design", "Tree Trimming", "Plantation Work", "Irrigation Setup"],
"mobile_repair": ["Screen Replacement", "Battery Replacement", "Software Fix", "Charging Port Repair", "Water Damage"],
"computer_repair": ["Desktop Repair", "Laptop Service", "Data Recovery", "Virus Removal", "Upgrade Service"],
}
CATEGORY_LIST = list(CATEGORIES.keys())
MALE_NAMES = [
"Arjun", "Rahul", "Karan", "Vikram", "Hardik", "Parth", "Dhruv", "Akash", "Jay", "Rohan",
"Manish", "Bhavesh", "Hitesh", "Mihir", "Rakesh", "Dinesh", "Mahesh", "Suresh", "Nilesh",
"Rajesh", "Prakash", "Deepak", "Sanjay", "Vijay", "Ajay", "Nikhil", "Amit", "Sunil", "Anil",
"Kiran", "Mayur", "Chetan", "Bhavin", "Chirag", "Harsh", "Kaushik", "Dharmesh", "Jignesh",
"Tejas", "Vishal", "Mukesh", "Ramesh", "Shailesh", "Jitendra", "Sandeep", "Devendra",
"Bharat", "Ashish", "Dhaval", "Keyur", "Sachin", "Ravi", "Savan", "Yash", "Krupal",
"Mitul", "Fenil", "Kishan", "Sagar", "Vatsal", "Harshad", "Kishor", "Pinakin", "Pravin",
"Kalpesh", "Ashok", "Gaurang", "Bipin", "Nirav", "Jayesh", "Milan", "Tushar", "Jatin",
"Yogesh", "Vinod", "Mohan", "Hasmukh", "Kantibhai", "Raman", "Shyam", "Tarun", "Umesh",
"Rushabh", "Helly", "Pruthvi", "Shubham", "Mohit", "Krunal", "Ronak", "Ankur", "Brijesh",
"Mitesh", "Parag", "Swapnil", "Akshay", "Pranav", "Kushal", "Darshan", "Siddharth",
]
FEMALE_NAMES = [
"Neha", "Priya", "Meena", "Rina", "Komal", "Pooja", "Sheetal", "Anjali", "Divya", "Kavita",
"Rupal", "Aarti", "Kiran", "Asha", "Deepa", "Hina", "Darshana", "Urvi", "Hetal", "Sejal",
"Bhavna", "Rutvi", "Kruti", "Nidhi", "Mansi", "Disha", "Trupti", "Ridhi", "Smita", "Alpa",
"Kinnari", "Shruti", "Reshma", "Jigna", "Mitali", "Krisha", "Jhanvi", "Heena", "Vaishali",
"Mamta", "Rekha", "Jyoti", "Rashmi", "Kajal", "Pinal", "Sonal", "Nisha", "Pallavi",
"Dipti", "Harsha", "Gauri", "Varsha", "Sangeeta", "Bhavika", "Hardika", "Niyati",
]
LAST_NAMES = [
"Patel", "Shah", "Makwana", "Joshi", "Rathod", "Solanki", "Parmar", "Savani", "Desai", "Mehta",
"Dave", "Trivedi", "Pandya", "Rawal", "Vyas", "Acharya", "Jani", "Thakkar", "Gajjar", "Bhavsar",
"Vasoya", "Savaliya", "Ramani", "Dobariya", "Kotadiya", "Vaghasiya", "Pipaliya", "Gohil",
"Jadav", "Vala", "Sarvaiya", "Rajput", "Chauhan", "Chavda", "Zala", "Padhiyar", "Rana",
"Vankar", "Barot", "Koli", "Rathva", "Damor", "Ninama",
"Bambhania", "Mevada", "Rank", "Mistry", "Suthar", "Luhar", "Kumbhar", "Vanzara",
]
STORE_PREFIXES = [
"Shree", "Om", "Jay", "Mahadev", "Royal", "Modern", "Perfect", "National",
"Super", "Metro", "City", "Star", "Prime", "Elite", "Supreme", "Apex",
"Krishna", "Ganesh", "Shiv", "Shakti", "Laxmi", "Sai", "Guru", "Sagar",
]
STORE_SUFFIXES = [
"Hardware", "Electricals", "Services", "Solutions", "Repair Center",
"Home Service", "Trading Co", "Enterprises", "Agency", "Store",
"Center", "Hub", "Point", "Corner", "House",
]
STREET_NAMES = [
"MG Road", "Station Road", "College Road", "Hospital Road", "Market Road",
"Tower Road", "Circle Road", "Cross Roads", "Main Bazaar", "Gandhi Marg",
"Nehru Marg", "Patel Marg", "Raj Marg", "School Road", "Temple Road",
"Masjid Road", "Lake Road", "Garden Road", "Park Road", "Bus Stand Road",
"Highway Road", "Railway Station Road", "Bypass Road", "Mall Road",
"Post Office Road", "Bank Road", "Court Road", "Library Road",
"Police Station Road", "Dargah Road", "Clock Tower Road", "Kacheri Road",
"Bamboo Bazaar", "Main Market Road", "Grain Market Road",
"Jalaram Marg", "Swaminarayan Marg", "Ambedkar Marg", "Tagore Marg",
"Shahid Bhagat Singh Marg", "Mahatma Gandhi Marg", "Sardar Patel Marg",
"Indira Gandhi Marg", "Subhash Marg", "Azad Marg", "Shyamal Cross Road",
"Satellite Road", "Bopal Road", "Science City Road", "Airport Road",
"Ring Road", "Sarkhej Road", "Narol Road", "Vatva Road",
"Panchwati Road", "Rambaug Road", "Nilkanth Mahadev Road",
"Vivekanand Road", "Surya Nagar Road", "Mahavir Nagar Road",
"Shastri Nagar Road", "Lal Darwaja Road", "Kuber Society Road",
]
LANDMARKS = [
"Hanuman Temple", "Bus Stand", "Railway Station", "Municipal Market",
"Post Office", "Police Station", "Government Hospital", "Main Square",
"Circle Garden", "Water Tank", "Overbridge", "Petrol Pump",
"Dargah", "Church", "Masjid", "Municipal Garden",
"Bus Depot", "ST Bus Stop", "Fire Station", "Court Building",
]
BIO_TEMPLATES = {
"plumbing": "Expert plumber with {exp} years experience in {area}, {city}. Specializing in pipe repair, drainage, water heater installation, and bathroom fittings.",
"electrical": "Certified electrician serving {area}, {city} for {exp} years. Expert in wiring, fan installation, switchboard repair, and smart home wiring.",
"cleaning": "Professional cleaner serving {area}, {city} with {exp} years of experience. Deep cleaning, kitchen, office, and sofa cleaning services.",
"carpentry": "Master carpenter with {exp} years in {area}, {city}. Custom furniture, door fitting, kitchen cabinets, and wood polishing.",
"painting": "Experienced painter with {exp} years in {area}, {city}. Wall painting, texture finishes, waterproofing, and exterior work.",
"ac": "AC specialist with {exp} years experience in {area}, {city}. Repair, service, gas refill, and installation of all AC brands.",
"salon": "Professional beautician serving {area}, {city} for {exp} years. Haircuts, styling, facial, bridal makeup, and grooming services.",
"vehicle": "Auto mechanic with {exp} years experience in {area}, {city}. Bike and car service, engine repair, tyre change, and denting.",
"pest_control": "Pest control expert with {exp} years in {area}, {city}. Cockroach, termite, mosquito, bed bug, and rodent treatments.",
"packers_movers": "Professional packer and mover with {exp} years in {area}, {city}. Safe and reliable shifting services for home and office.",
"photography": "Professional photographer with {exp} years in {area}, {city}. Wedding, portrait, event, and product photography services.",
"catering": "Experienced caterer serving {area}, {city} for {exp} years. Home, party, and wedding catering with delicious Gujarati cuisine.",
"laundry": "Laundry professional with {exp} years in {area}, {city}. Wash, fold, iron, dry cleaning, and carpet cleaning services.",
"tailoring": "Master tailor with {exp} years experience in {area}, {city}. Custom stitching, alterations, and designer wear for men and women.",
"fitness": "Certified fitness trainer with {exp} years in {area}, {city}. Personal training, yoga, diet planning, and gym sessions.",
"tutoring": "Experienced tutor with {exp} years teaching in {area}, {city}. Home tuition, exam prep, and subject coaching for all grades.",
"home_renovation": "Home renovation expert with {exp} years in {area}, {city}. Full renovation, kitchen remodel, bathroom work, and flooring.",
"interior_design": "Interior designer with {exp} years experience in {area}, {city}. Home interiors, office design, space planning, and decor.",
"appliance_repair": "Appliance repair expert with {exp} years in {area}, {city}. Washing machine, fridge, microwave, and water purifier service.",
"roofing": "Roofing specialist with {exp} years in {area}, {city}. Waterproofing, terrace sealing, roof repair, and coating services.",
"flooring": "Flooring expert with {exp} years in {area}, {city}. Tile installation, marble polishing, wood and vinyl flooring work.",
"welding": "Skilled welder with {exp} years experience in {area}, {city}. Gate fabrication, railing, grill making, and structural welding.",
"event_planning": "Event planner with {exp} years in {area}, {city}. Birthday, wedding, corporate events, decoration, and coordination.",
"security": "Security professional with {exp} years in {area}, {city}. CCTV installation, biometric systems, alarm setup, and security guard.",
"gardening": "Gardening expert with {exp} years in {area}, {city}. Lawn care, garden design, tree trimming, and irrigation setup.",
"mobile_repair": "Mobile repair technician with {exp} years in {area}, {city}. Screen, battery, software, charging port, and water damage repairs.",
"computer_repair": "Computer repair expert with {exp} years in {area}, {city}. Desktop, laptop, data recovery, virus removal, and upgrades.",
}
DESCRIPTION_TEMPLATES = {
"plumbing": "Full-service plumbing store in {area}, {city}. Stocking pipes, fittings, bathroom fixtures, water heaters, and all plumbing essentials.",
"electrical": "Complete electrical supply store in {area}, {city}. Wires, switches, MCBs, fans, lights, and electrical accessories.",
"cleaning": "Cleaning supplies and equipment store in {area}, {city}. Chemicals, tools, vacuum cleaners, and professional cleaning products.",
"carpentry": "Carpentry materials and hardware store in {area}, {city}. Wood, tools, fittings, kitchen components, and finishing supplies.",
"painting": "Paint store in {area}, {city}. All brands, wide color range, brushes, rollers, thinners, and waterproofing solutions.",
"ac": "AC sales and service center in {area}, {city}. Units, spare parts, tools, gas, and all cooling accessories.",
"salon": "Salon supplies store in {area}, {city}. Products, tools, chairs, mirrors, and professional salon equipment.",
"vehicle": "Auto parts and accessories store in {area}, {city}. Spares, tires, batteries, lubricants, and vehicle service tools.",
"pest_control": "Pest control product store in {area}, {city}. Chemicals, sprays, traps, fumigation equipment, and safety gear.",
"packers_movers": "Moving and packing supplies store in {area}, {city}. Boxes, tapes, bubble wrap, ropes, and moving equipment.",
"photography": "Photography equipment store in {area}, {city}. Cameras, lenses, lights, backdrops, and studio accessories.",
"catering": "Catering supplies store in {area}, {city}. Utensils, disposables, serving equipment, and party essentials.",
"laundry": "Laundry and dry cleaning store in {area}, {city}. Wash, fold, iron, dry clean, and specialty fabric care.",
"tailoring": "Tailoring shop in {area}, {city}. Fabrics, threads, accessories, and custom stitching services.",
"fitness": "Fitness equipment store in {area}, {city}. Weights, mats, machines, supplements, and workout accessories.",
"tutoring": "Educational resource center in {area}, {city}. Books, materials, worksheets, and learning aids for all subjects.",
"home_renovation": "Home renovation materials store in {area}, {city}. Tiles, cement, paint, plumbing and electrical supplies.",
"interior_design": "Interior solutions store in {area}, {city}. Fabrics, wallpapers, decor items, furniture, and lighting.",
"appliance_repair": "Appliance repair center in {area}, {city}. Spare parts, tools, and service for all home appliances.",
"roofing": "Roofing and waterproofing store in {area}, {city}. Waterproofing solutions, membranes, coatings, and sealants.",
"flooring": "Flooring solutions store in {area}, {city}. Tiles, marble, wood, vinyl, and installation tools.",
"welding": "Welding supplies store in {area}, {city}. Rods, machines, gas cylinders, safety gear, and fabrication tools.",
"event_planning": "Event supply store in {area}, {city}. Decor, tents, lights, chairs, sound systems, and party supplies.",
"security": "Security solutions store in {area}, {city}. Cameras, alarms, locks, biometric systems, and surveillance equipment.",
"gardening": "Garden supplies store in {area}, {city}. Plants, seeds, pots, fertilizers, tools, and irrigation systems.",
"mobile_repair": "Mobile accessories and repair store in {area}, {city}. Parts, tools, screens, batteries, and phone accessories.",
"computer_repair": "Computer service center in {area}, {city}. Parts, accessories, cables, tools, and repair services.",
}
TAGS_BY_CATEGORY = {
"plumbing": ["pipe", "leak", "bathroom", "tap", "drain", "water", "heater", "fitting"],
"electrical": ["wiring", "fan", "light", "MCB", "switch", "smart", "electric"],
"cleaning": ["deep clean", "kitchen", "office", "sofa", "carpet", "bathroom"],
"carpentry": ["furniture", "door", "cabinet", "wood", "kitchen", "custom"],
"painting": ["wall paint", "texture", "exterior", "waterproof", "spray"],
"ac": ["AC", "cooling", "gas refill", "repair", "installation"],
"salon": ["haircut", "beard", "facial", "makeup", "grooming", "beauty"],
"vehicle": ["bike", "car", "tyre", "engine", "battery", "service"],
"pest_control": ["pest", "termite", "mosquito", "cockroach", "rodent", "fumigation"],
"packers_movers": ["shifting", "relocation", "packing", "loading", "moving"],
"photography": ["wedding", "portrait", "event", "product", "cinema"],
"catering": ["catering", "party", "wedding", "food", "home delivery"],
"laundry": ["wash", "dry clean", "iron", "fold", "carpet"],
"tailoring": ["stitching", "alteration", "designer", "uniform", "custom"],
"fitness": ["gym", "yoga", "trainer", "diet", "zumba", "workout"],
"tutoring": ["tuition", "classes", "subject", "exam", "coaching"],
"home_renovation": ["renovation", "remodel", "kitchen", "bathroom", "flooring"],
"interior_design": ["interior", "design", "decor", "furniture", "space"],
"appliance_repair": ["washing machine", "fridge", "microwave", "purifier", "geyser"],
"roofing": ["roof", "waterproof", "terrace", "sealing", "coating"],
"flooring": ["tiles", "marble", "wood", "vinyl", "grouting"],
"welding": ["gate", "railing", "grill", "fabrication", "aluminum"],
"event_planning": ["party", "wedding", "decoration", "event", "planning"],
"security": ["CCTV", "alarm", "biometric", "security", "surveillance"],
"gardening": ["garden", "lawn", "plants", "irrigation", "landscaping"],
"mobile_repair": ["mobile", "screen", "battery", "software", "repair"],
"computer_repair": ["computer", "laptop", "data", "virus", "upgrade"],
}
CERTIFICATIONS_BY_CATEGORY = {
"plumbing": ["Plumbing Diploma", "Water Systems Certification", "Safety Training"],
"electrical": ["Electrical License", "Wiring Certification", "Safety Training"],
"cleaning": ["Deep Cleaning Certified", "Chemical Safety Training"],
"carpentry": ["Carpentry Diploma", "Woodworking Certification"],
"painting": ["Painting & Coating Certified", "Color Design Certification"],
"ac": ["HVAC Certified", "AC Manufacturer Training", "Gas Handling License"],
"salon": ["Beauty License", "Salon Management Certified", "Hair Styling Diploma"],
"vehicle": ["Auto Mechanic Diploma", "EV Certification", "Safety Inspection License"],
"pest_control": ["Pest Control License", "Chemical Handling Certified", "Fumigation License"],
"packers_movers": ["Moving License", "Insurance Certified", "Safety Training"],
"photography": ["Professional Photography Diploma", "Adobe Certified"],
"catering": ["Food Safety Certified", "Hospitality Diploma", "FSSAI License"],
"laundry": ["Dry Cleaning Certified", "Fabric Care Training"],
"tailoring": ["Fashion Design Diploma", "Tailoring Certificate"],
"fitness": ["Personal Trainer Certified", "Yoga Teacher Training", "Nutrition Certified"],
"tutoring": ["Teaching License", "Subject Specialist Certified", "CTET Qualified"],
"home_renovation": ["Contractor License", "Safety Certified", "Project Management"],
"interior_design": ["Interior Design Degree", "AutoCAD Certified", "Space Planning"],
"appliance_repair": ["Appliance Repair Certified", "Electronics Diploma"],
"roofing": ["Roofing Contractor License", "Waterproofing Certified"],
"flooring": ["Flooring Installation Certified", "Marble Polishing Training"],
"welding": ["Welding Diploma", "Arc Welding Certified", "Safety Training"],
"event_planning": ["Event Management Diploma", "Wedding Planning Certified"],
"security": ["Security License", "CCTV Installation Certified", "Biometric Training"],
"gardening": ["Horticulture Diploma", "Landscape Design Certified"],
"mobile_repair": ["Mobile Repair Diploma", "Manufacturer Certified"],
"computer_repair": ["CompTIA A+", "Hardware Diploma", "Networking Certified"],
}
# ─── Helpers ─────────────────────────────────────────────────
def random_phone():
return f"+91{random.randint(6000000000, 9999999999)}"
def random_email(name):
clean = re.sub(r'[^a-z0-9]', '', name.lower().replace(" ", "."))
return f"{clean}{random.randint(1,999)}@gmail.com"
def random_rating():
return round(random.uniform(3.5, 5.0), 1)
def dice_avatar(seed):
return DICE_BEAR % seed.replace(" ", "%20")
def pick_languages():
return random.sample(LANGUAGES, random.randint(1, 3))
def pick_tags(category):
base = TAGS_BY_CATEGORY.get(category, [category])
return random.sample(base, k=min(random.randint(2, 5), len(base)))
def pick_certifications(category):
certs = CERTIFICATIONS_BY_CATEGORY.get(category, [])
if not certs: return []
return random.sample(certs, k=random.randint(1, min(2, len(certs))))
def generate_services(category, is_worker=True):
services_list = CATEGORIES.get(category, ["General Service"])
selected = random.sample(services_list, k=min(random.randint(2, 4), len(services_list)))
result = []
for s in selected:
price = random.randint(150, 2500) if is_worker else random.randint(200, 8000)
stype = random.choice(["per_hour", "per_job"]) if is_worker else "per_job"
result.append({"name": s, "price": price, "type": stype})
return result
def random_gujarati_name():
gender = random.choice(["male", "female"])
first = random.choice(MALE_NAMES if gender == "male" else FEMALE_NAMES)
last = random.choice(LAST_NAMES)
return f"{first} {last}"
def random_store_name(category, area):
prefix = random.choice(STORE_PREFIXES)
suffix = random.choice(STORE_SUFFIXES)
base = f"{prefix} {suffix}"
return random.choice([
f"{base} {area}",
f"{prefix} {category.title()} {suffix}",
f"{area} {suffix}",
f"{base}",
])
def km_to_deg(lat, km):
dlat = km / 111.0
dlng = km / (111.0 * math.cos(math.radians(lat)))
return dlat, dlng
def generate_grid(lat_center, lng_center, width_km, height_km, spacing_km):
dlat, dlng = km_to_deg(lat_center, spacing_km)
hw_km, hh_km = width_km / 2.0, height_km / 2.0
lat_start = lat_center - km_to_deg(lat_center, hh_km)[0]
lng_start = lng_center - km_to_deg(lat_center, hw_km)[1]
lat_steps = max(1, int(height_km / spacing_km))
lng_steps = max(1, int(width_km / spacing_km))
jitter = spacing_km * 0.2
jlat, jlng = km_to_deg(lat_center, jitter)
points = []
for i in range(lat_steps):
for j in range(lng_steps):
lat = lat_start + (i + 0.5) * dlat + random.uniform(-jlat, jlat)
lng = lng_start + (j + 0.5) * dlng + random.uniform(-jlng, jlng)
points.append((lat, lng))
return points
def nearest_area(lat, lng, city):
areas = CITY_AREAS.get(city, [city])
idx = int(abs(hash(f"{lat:.4f}{lng:.4f}")) % len(areas))
return areas[idx]
def generate_address(city, area):
street = random.choice(STREET_NAMES)
num = random.randint(1, 150)
landmark = random.choice(LANDMARKS)
fmt = random.choice(["number_street", "near_landmark", "street_area"])
if fmt == "number_street":
return f"{num}, {street}, {area}, {city}, Gujarat"
elif fmt == "near_landmark":
street2 = random.choice(STREET_NAMES)
return f"Near {landmark}, {street2}, {area}, {city}, Gujarat"
else:
return f"{street}, {area}, {city}, Gujarat"
def create_worker(city, street_addr, area, lat, lng, category):
name = random_gujarati_name()
exp = random.randint(1, 25)
services = generate_services(category, is_worker=True)
tags = pick_tags(category)
certs = pick_certifications(category)
langs = pick_languages()
price = random.randint(150, 1200)
rating = random_rating()
reviews = random.randint(3, 800)
jobs = random.randint(5, 3000)
bio = BIO_TEMPLATES.get(category, "{category} specialist serving {area}, {city}.").format(
exp=exp, area=area, city=city
)
return {
"name": name,
"email": random_email(name),
"phone": random_phone(),
"whatsapp": random_phone(),
"avatar": dice_avatar(name),
"city": city,
"area": area,
"category": category,
"services": services,
"bio": bio,
"experience": exp,
"rating": rating,
"total_reviews": reviews,
"total_jobs": jobs,
"price_per_hour": price,
"lat": lat,
"lng": lng,
"address": street_addr,
"available": random.random() > 0.15,
"verified": random.random() > (0.45 if reviews > 50 else 0.7),
"emergency_available": random.random() > 0.75,
"response_time": random.choice([15, 30, 45, 60]),
"languages": langs,
"certifications": certs,
"service_areas": [],
"tags": tags,
"gallery": [],
}
def create_store(city, street_addr, area, lat, lng, category):
name = random_store_name(category, area)
services = generate_services(category, is_worker=False)
tags = pick_tags(category)
langs = pick_languages()
rating = random_rating()
reviews = random.randint(3, 500)
description = DESCRIPTION_TEMPLATES.get(category, "{category} store in {area}, {city}.").format(
category=category.title(), area=area, city=city
)
open_hours_list = [
"9:00 AM - 9:00 PM", "10:00 AM - 8:00 PM", "9:30 AM - 7:30 PM",
"8:00 AM - 10:00 PM", "10:00 AM - 9:00 PM", "9:00 AM - 6:00 PM",
]
return {
"name": name,
"email": random_email(name),
"phone": random_phone(),
"whatsapp": random_phone(),
"avatar": dice_avatar(name),
"city": city,
"area": area,
"category": category,
"services": services,
"description": description,
"rating": rating,
"total_reviews": reviews,
"lat": lat,
"lng": lng,
"address": street_addr,
"verified": random.random() > 0.4,
"open_hours": random.choice(open_hours_list),
"emergency_available": random.random() > 0.8,
"languages": langs,
"tags": tags,
"gallery": [],
}
# ─── PostgreSQL Bulk Insert ──────────────────────────────────
def insert_workers_batch(cur, workers):
if not workers: return
args_list = []
for w in workers:
args_list.append((
w["name"], w["email"], w["phone"], w["whatsapp"], w["avatar"],
w["city"], w["area"], w["category"], w["bio"],
w["experience"], w["rating"], w["total_reviews"], w["total_jobs"], w["price_per_hour"],
w["lng"], w["lat"], w["address"],
w["available"], w["verified"], w["emergency_available"], w["response_time"],
w["languages"], w["certifications"], w["service_areas"], w["tags"], w["gallery"],
))
sql = """
INSERT INTO workers (user_id, name, email, phone, whatsapp, avatar, city, area, category, bio,
experience, rating, total_reviews, total_jobs, price_per_hour,
location, address, available, verified, emergency_available, response_time,
languages, certifications, service_areas, tags, gallery)
VALUES %s
RETURNING id
"""
template = """(
NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s,
ST_SetSRID(ST_MakePoint(%s, %s), 4326)::geography, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s
)"""
returned_ids = psycopg2.extras.execute_values(
cur, sql, args_list, template=template, page_size=1000, fetch=True
)
services_args = []
for w, (worker_id,) in zip(workers, returned_ids):
for svc in w["services"]:
services_args.append((
worker_id, svc["name"], svc["price"], svc["type"]
))
if services_args:
psycopg2.extras.execute_values(
cur,
"INSERT INTO worker_services (worker_id, name, price, service_type) VALUES %s",
services_args,
page_size=1000
)
def insert_stores_batch(cur, stores):
if not stores: return
args_list = []
for s in stores:
args_list.append((
s["name"], s["email"], s["phone"], s["whatsapp"], s["avatar"],
s["city"], s["area"], s["category"], s["description"],
s["rating"], s["total_reviews"], s["lng"], s["lat"], s["address"],
s["verified"], s["open_hours"], s["emergency_available"],
s["languages"], s["tags"], s["gallery"],
))
sql = """
INSERT INTO stores (name, email, phone, whatsapp, avatar, city, area, category, description,
rating, total_reviews, location, address, verified, open_hours, emergency_available,
languages, tags, gallery)
VALUES %s
RETURNING id
"""
template = """(
%s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, ST_SetSRID(ST_MakePoint(%s, %s), 4326)::geography, %s, %s, %s, %s,
%s, %s, %s
)"""
returned_ids = psycopg2.extras.execute_values(
cur, sql, args_list, template=template, page_size=1000, fetch=True
)
services_args = []
for s, (store_id,) in zip(stores, returned_ids):
for svc in s["services"]:
services_args.append((
store_id, svc["name"], svc["price"], svc["type"]
))
if services_args:
psycopg2.extras.execute_values(
cur,
"INSERT INTO store_services (store_id, name, price, service_type) VALUES %s",
services_args,
page_size=1000
)
# ─── Main seed ────────────────────────────────────────────────
def seed():
print("=" * 65)
print(" GUJARAT STREET-GRID SEED v3.0 β€” PostgreSQL")
print(" Cities: {} | Categories: {}".format(len(CITIES), len(CATEGORIES)))
print("=" * 65)
if not DATABASE_URL:
print("❌ DATABASE_URL not set in .env")
sys.exit(1)
conn = psycopg2.connect(DATABASE_URL)
conn.autocommit = False
cur = conn.cursor()
if CLEAR_EXISTING:
print("\nπŸ—‘ Clearing existing data...")
cur.execute("DELETE FROM worker_services")
cur.execute("DELETE FROM store_services")
cur.execute("DELETE FROM workers")
cur.execute("DELETE FROM stores")
conn.commit()
print(" Cleared workers, stores, and services")
print("\nπŸ“ Generating grid points per city...")
city_grids = {}
total_points = 0
for cname, (clat, clng, w, h, s) in sorted(CITIES.items()):
pts = generate_grid(clat, clng, w, h, s)
city_grids[cname] = pts
total_points += len(pts)
areas = CITY_AREAS.get(cname, [cname])
print(f" {cname}: {len(pts)} grid points Γ— {len(areas)} areas")
print(f"\n Total grid points across all cities: {total_points}")
print(f" Target: ~{total_points * 4} docs ({total_points * 3} workers + {total_points} stores)")
all_workers_count = 0
all_stores_count = 0
used_name_hashes = set()
for cname, points in sorted(city_grids.items()):
areas = CITY_AREAS.get(cname, [cname])
print(f"\n{'='*40}")
print(f" {cname} ({len(points)} points)")
print(f"{'='*40}")
city_workers = []
city_stores = []
cat_tracker = {cat: {"workers": 0, "stores": 0} for cat in CATEGORY_LIST}
for idx, (lat, lng) in enumerate(points):
area = nearest_area(lat, lng, cname)
street_addr = generate_address(cname, area)
worker_cats = random.sample(CATEGORY_LIST, 3)
for wcat in worker_cats:
w = create_worker(cname, street_addr, area, lat, lng, wcat)
h = hash(w["name"]) % 10**12
if h not in used_name_hashes:
used_name_hashes.add(h)
city_workers.append(w)
cat_tracker[wcat]["workers"] += 1
scat = random.choice(CATEGORY_LIST)
s = create_store(cname, street_addr, area, lat, lng, scat)
h = hash(s["name"]) % 10**12
if h not in used_name_hashes:
used_name_hashes.add(h)
city_stores.append(s)
cat_tracker[scat]["stores"] += 1
cats_covered_w = sum(1 for v in cat_tracker.values() if v["workers"] > 0)
cats_covered_s = sum(1 for v in cat_tracker.values() if v["stores"] > 0)
print(f" Workers: {len(city_workers)} (covers {cats_covered_w}/{len(CATEGORY_LIST)} categories)")
print(f" Stores: {len(city_stores)} (covers {cats_covered_s}/{len(CATEGORY_LIST)} categories)")
# Insert in batches
print(" Inserting workers...")
insert_workers_batch(cur, city_workers)
conn.commit()
all_workers_count += len(city_workers)
print(" Inserting stores...")
insert_stores_batch(cur, city_stores)
conn.commit()
all_stores_count += len(city_stores)
print(f"\n{'='*40}")
print(f" SEED COMPLETE")
print(f"{'='*40}")
print(f" Workers: {all_workers_count}")
print(f" Stores: {all_stores_count}")
print(f" Total: {all_workers_count + all_stores_count}")
cur.close()
conn.close()
print(f"\nπŸŽ‰ Done!")
if __name__ == "__main__":
seed()