Team Ai
Apppublic

prazy1208/text2sql

sourceHugging Faceupdated 5mo agoView on Hugging Face
0likes
generate_data.py303 linesDownload Raw Back to root
1"""2Generate synthetic data for healthcare_schema, retail_schema, and finance_schema.3Uses Faker, pandas, and SQLAlchemy. Loads DB credentials from .env.4Run: python generate_data.py5"""6 7import logging8import os9from datetime import timedelta10 11import pandas as pd12from dotenv import load_dotenv13from faker import Faker14from sqlalchemy import create_engine, text15 16# ---------------------------------------------------------------------------17# Logging18# ---------------------------------------------------------------------------19logging.basicConfig(20    level=logging.INFO,21    format="%(asctime)s [%(levelname)s] %(message)s",22    datefmt="%Y-%m-%d %H:%M:%S",23)24logger = logging.getLogger(__name__)25 26# Load .env before reading env vars27load_dotenv()28 29# ---------------------------------------------------------------------------30# Engine31# ---------------------------------------------------------------------------32 33 34def get_engine():35    """Build SQLAlchemy engine from .env (DATABASE_URL or DB_* variables)."""36    database_url = os.getenv("DATABASE_URL")37    if database_url:38        return create_engine(database_url)39    host = os.getenv("DB_HOST", "localhost")40    port = os.getenv("DB_PORT", "5432")41    user = os.getenv("DB_USER", "postgres")42    password = os.getenv("DB_PASSWORD", "")43    dbname = os.getenv("DB_NAME", "postgres")44    url = f"postgresql://{user}:{password}@{host}:{port}/{dbname}"45    return create_engine(url)46 47 48def _sync_sequence(engine, schema: str, table: str, column: str):49    """Set the table's SERIAL sequence to the current max value."""50    stmt = text(51        f"SELECT setval(pg_get_serial_sequence('{schema}.{table}', '{column}'), "52        f"(SELECT COALESCE(MAX({column}), 1) FROM {schema}.{table}))"53    )54    with engine.connect() as conn:55        conn.execute(stmt)56        conn.commit()57 58 59# ---------------------------------------------------------------------------60# Healthcare61# ---------------------------------------------------------------------------62 63INSURANCE_TYPES = ["Medicare", "Medicaid", "Private", "Employer", "Uninsured"]64GENDERS = ["Male", "Female", "Other"]65DEPARTMENTS = ["Emergency", "Surgery", "Cardiology", "Neurology", "Pediatrics", "Oncology", "General"]66VISIT_TYPES = ["Inpatient", "Outpatient", "Emergency", "Follow-up"]67SEVERITY_LEVELS = ["Low", "Medium", "High", "Critical"]68DIAGNOSIS_CODES = ["ICD-10-A01", "ICD-10-B02", "ICD-10-C03", "ICD-10-D04", "ICD-10-E05", "ICD-10-F06", "ICD-10-G07", "ICD-10-H08"]69 70 71def generate_healthcare_data(engine):72    """Generate patients (1000), visits (2000), diagnoses (3000) in healthcare_schema."""73    fake = Faker()74    fake.seed_instance(42)75    logger.info("Generating healthcare_schema data...")76 77    # Patients: 100078    n_patients = 100079    patients = []80    for i in range(1, n_patients + 1):81        reg_date = fake.date_between(start_date="-5y", end_date="today")82        dob = fake.date_between(start_date="-90y", end_date="-18y")83        patients.append({84            "patient_id": i,85            "first_name": fake.first_name(),86            "last_name": fake.last_name(),87            "date_of_birth": dob,88            "gender": fake.random_element(GENDERS),89            "city": fake.city(),90            "state": fake.state_abbr(),91            "insurance_type": fake.random_element(INSURANCE_TYPES),92            "registration_date": reg_date,93        })94    df_patients = pd.DataFrame(patients)95    df_patients.to_sql("patients", engine, schema="healthcare_schema", if_exists="append", index=False)96    logger.info("  Inserted %d patients.", len(df_patients))97 98    # Visits: 2000 (linked to patients)99    n_visits = 2000100    visits = []101    for i in range(1, n_visits + 1):102        patient_id = fake.random_int(min=1, max=n_patients)103        admission = fake.date_between(start_date="-2y", end_date="today")104        discharge = admission + timedelta(days=fake.random_int(min=0, max=14))105        cost = round(float(fake.random_number(digits=4, fix_len=False)) + fake.random.random() * 100, 2)106        visits.append({107            "visit_id": i,108            "patient_id": patient_id,109            "admission_date": admission,110            "discharge_date": discharge,111            "department": fake.random_element(DEPARTMENTS),112            "visit_type": fake.random_element(VISIT_TYPES),113            "total_cost": cost,114        })115    df_visits = pd.DataFrame(visits)116    df_visits.to_sql("visits", engine, schema="healthcare_schema", if_exists="append", index=False)117    logger.info("  Inserted %d visits.", len(df_visits))118 119    # Diagnoses: 3000 (linked to visits)120    n_diagnoses = 3000121    diagnoses = []122    for i in range(1, n_diagnoses + 1):123        visit_id = fake.random_int(min=1, max=n_visits)124        code = fake.random_element(DIAGNOSIS_CODES) + "-" + str(fake.random_int(10, 99))125        diagnoses.append({126            "diagnosis_id": i,127            "visit_id": visit_id,128            "diagnosis_code": code,129            "diagnosis_description": fake.sentence(nb_words=6),130            "severity_level": fake.random_element(SEVERITY_LEVELS),131        })132    df_diagnoses = pd.DataFrame(diagnoses)133    df_diagnoses.to_sql("diagnoses", engine, schema="healthcare_schema", if_exists="append", index=False)134    logger.info("  Inserted %d diagnoses.", len(df_diagnoses))135    for tbl, col in [("patients", "patient_id"), ("visits", "visit_id"), ("diagnoses", "diagnosis_id")]:136        _sync_sequence(engine, "healthcare_schema", tbl, col)137    logger.info("Healthcare data generation complete.")138 139 140# ---------------------------------------------------------------------------141# Retail142# ---------------------------------------------------------------------------143 144CATEGORIES = ["Electronics", "Clothing", "Home", "Sports", "Books", "Toys", "Health", "Grocery"]145BRANDS = ["Acme", "Beta", "Gamma", "Delta", "Epsilon", "Zeta", "Omega"]146 147 148def generate_retail_data(engine):149    """Generate customers (1000), products (500), orders (3000) in retail_schema."""150    fake = Faker()151    fake.seed_instance(43)152    logger.info("Generating retail_schema data...")153 154    # Customers: 1000155    n_customers = 1000156    customers = []157    for i in range(1, n_customers + 1):158        first, last = fake.first_name(), fake.last_name()159        customers.append({160            "customer_id": i,161            "first_name": first,162            "last_name": last,163            "email": fake.ascii_safe_email(),164            "city": fake.city(),165            "state": fake.state_abbr(),166            "signup_date": fake.date_between(start_date="-3y", end_date="today"),167        })168    df_customers = pd.DataFrame(customers)169    df_customers.to_sql("customers", engine, schema="retail_schema", if_exists="append", index=False)170    logger.info("  Inserted %d customers.", len(df_customers))171 172    # Products: 500173    n_products = 500174    products = []175    for i in range(1, n_products + 1):176        price = round(fake.random.uniform(5.0, 500.0), 2)177        products.append({178            "product_id": i,179            "product_name": fake.catch_phrase().replace(".", ""),180            "category": fake.random_element(CATEGORIES),181            "brand": fake.random_element(BRANDS),182            "price": price,183            "launch_date": fake.date_between(start_date="-4y", end_date="today"),184        })185    df_products = pd.DataFrame(products)186    df_products.to_sql("products", engine, schema="retail_schema", if_exists="append", index=False)187    logger.info("  Inserted %d products.", len(df_products))188 189    # Orders: 3000 (linked to customers and products)190    n_orders = 3000191    orders = []192    for i in range(1, n_orders + 1):193        customer_id = fake.random_int(min=1, max=n_customers)194        product_id = fake.random_int(min=1, max=n_products)195        quantity = fake.random_int(min=1, max=10)196        # Price looked up would require a join; use a plausible total197        unit_price = fake.random.uniform(5.0, 500.0)198        total_amount = round(quantity * unit_price, 2)199        orders.append({200            "order_id": i,201            "customer_id": customer_id,202            "product_id": product_id,203            "order_date": fake.date_between(start_date="-2y", end_date="today"),204            "quantity": quantity,205            "total_amount": total_amount,206        })207    df_orders = pd.DataFrame(orders)208    df_orders.to_sql("orders", engine, schema="retail_schema", if_exists="append", index=False)209    logger.info("  Inserted %d orders.", len(df_orders))210    for tbl, col in [("customers", "customer_id"), ("products", "product_id"), ("orders", "order_id")]:211        _sync_sequence(engine, "retail_schema", tbl, col)212    logger.info("Retail data generation complete.")213 214 215# ---------------------------------------------------------------------------216# Finance217# ---------------------------------------------------------------------------218 219ACCOUNT_TYPES = ["savings", "checking"]220TRANSACTION_TYPES = ["debit", "credit"]221LOAN_TYPES = ["home", "auto", "personal"]222 223 224def generate_finance_data(engine):225    """Generate accounts (1000), transactions (5000), loans (800) in finance_schema."""226    fake = Faker()227    fake.seed_instance(44)228    logger.info("Generating finance_schema data...")229 230    # Accounts: 1000231    n_accounts = 1000232    accounts = []233    for i in range(1, n_accounts + 1):234        balance = round(fake.random.uniform(100.0, 100000.0), 2)235        accounts.append({236            "account_id": i,237            "customer_name": fake.name(),238            "account_type": fake.random_element(ACCOUNT_TYPES),239            "branch_city": fake.city(),240            "opening_date": fake.date_between(start_date="-10y", end_date="today"),241            "current_balance": balance,242        })243    df_accounts = pd.DataFrame(accounts)244    df_accounts.to_sql("accounts", engine, schema="finance_schema", if_exists="append", index=False)245    logger.info("  Inserted %d accounts.", len(df_accounts))246 247    # Transactions: 5000 (linked to accounts)248    n_transactions = 5000249    transactions = []250    for i in range(1, n_transactions + 1):251        account_id = fake.random_int(min=1, max=n_accounts)252        ttype = fake.random_element(TRANSACTION_TYPES)253        amount = round(fake.random.uniform(10.0, 5000.0), 2)254        transactions.append({255            "transaction_id": i,256            "account_id": account_id,257            "transaction_date": fake.date_between(start_date="-1y", end_date="today"),258            "transaction_type": ttype,259            "amount": amount,260            "description": fake.sentence(nb_words=4),261        })262    df_transactions = pd.DataFrame(transactions)263    df_transactions.to_sql("transactions", engine, schema="finance_schema", if_exists="append", index=False)264    logger.info("  Inserted %d transactions.", len(df_transactions))265 266    # Loans: 800 (linked to accounts)267    n_loans = 800268    loans = []269    for i in range(1, n_loans + 1):270        account_id = fake.random_int(min=1, max=n_accounts)271        start_date = fake.date_between(start_date="-5y", end_date="today")272        end_date = start_date + timedelta(days=fake.random_int(365, 3600))273        loan_amount = round(fake.random.uniform(5000.0, 500000.0), 2)274        rate = round(fake.random.uniform(3.0, 15.0), 2)275        loans.append({276            "loan_id": i,277            "account_id": account_id,278            "loan_type": fake.random_element(LOAN_TYPES),279            "loan_amount": loan_amount,280            "interest_rate": rate,281            "loan_start_date": start_date,282            "loan_end_date": end_date,283        })284    df_loans = pd.DataFrame(loans)285    df_loans.to_sql("loans", engine, schema="finance_schema", if_exists="append", index=False)286    logger.info("  Inserted %d loans.", len(df_loans))287    for tbl, col in [("accounts", "account_id"), ("transactions", "transaction_id"), ("loans", "loan_id")]:288        _sync_sequence(engine, "finance_schema", tbl, col)289    logger.info("Finance data generation complete.")290 291 292# ---------------------------------------------------------------------------293# Main294# ---------------------------------------------------------------------------295 296if __name__ == "__main__":297    logger.info("Starting data generation.")298    engine = get_engine()299    generate_healthcare_data(engine)300    generate_retail_data(engine)301    generate_finance_data(engine)302    logger.info("All data generation finished.")303