ecommerce-agent / scripts /setup_database.py
Mohitcr1
Fix contradictory logic: Conditional tone based on delivery timing, frustration threshold 0.5, celebrate early deliveries
d84e2c7
Raw
History Blame Contribute Delete
4.89 kB
import sqlite3
import pandas as pd
import os
from pathlib import Path
RAW = Path("data/raw")
DB = Path("data/olist.db")
TABLE_MAP = {
"olist_customers_dataset.csv": "customers",
"olist_orders_dataset.csv": "orders",
"olist_order_items_dataset.csv": "order_items",
"olist_order_payments_dataset.csv": "order_payments",
"olist_order_reviews_dataset.csv": "order_reviews",
"olist_products_dataset.csv": "products",
"olist_sellers_dataset.csv": "sellers",
"olist_geolocation_dataset.csv": "geolocation",
"product_category_name_translation.csv": "category_translation",
}
def load_tables(conn):
"""Load CSV files into SQLite tables"""
for filename, table in TABLE_MAP.items():
filepath = RAW / filename
if not filepath.exists():
print(f" ⚠ Skipping {table} - file not found: {filepath}")
continue
df = pd.read_csv(filepath, low_memory=False)
df.to_sql(table, conn, if_exists="replace", index=False)
print(f" ✓ Loaded {table} ({len(df)} rows)")
def create_indexes(conn):
"""Create indexes for faster queries"""
indexes = [
"CREATE INDEX IF NOT EXISTS idx_orders_id ON orders(order_id)",
"CREATE INDEX IF NOT EXISTS idx_orders_customer ON orders(customer_id)",
"CREATE INDEX IF NOT EXISTS idx_items_order ON order_items(order_id)",
"CREATE INDEX IF NOT EXISTS idx_items_product ON order_items(product_id)",
"CREATE INDEX IF NOT EXISTS idx_items_seller ON order_items(seller_id)",
"CREATE INDEX IF NOT EXISTS idx_reviews_order ON order_reviews(order_id)",
"CREATE INDEX IF NOT EXISTS idx_payments_order ON order_payments(order_id)",
]
for idx in indexes:
conn.execute(idx)
print(" ✓ Indexes created")
def create_views(conn):
"""Create composite views for common queries"""
# Use dataset reference date (2018-09-03 - last order date in dataset)
DEMO_DATE = '2018-09-03'
# Main composite view — single query for full order info
conn.execute(f"""
CREATE VIEW IF NOT EXISTS v_order_full AS
SELECT
o.order_id,
o.customer_id,
o.order_status,
o.order_purchase_timestamp,
o.order_approved_at,
o.order_delivered_carrier_date,
o.order_delivered_customer_date,
o.order_estimated_delivery_date,
ROUND(SUM(oi.price + oi.freight_value), 2) AS total_amount,
COUNT(oi.order_item_id) AS item_count,
GROUP_CONCAT(DISTINCT oi.seller_id) AS seller_ids,
GROUP_CONCAT(DISTINCT p.payment_type) AS payment_methods,
CASE
WHEN o.order_delivered_customer_date IS NOT NULL
AND o.order_delivered_customer_date > o.order_estimated_delivery_date
THEN 1
WHEN o.order_delivered_customer_date IS NULL
AND o.order_status NOT IN ('delivered', 'canceled')
AND DATE('{DEMO_DATE}') > DATE(o.order_estimated_delivery_date)
THEN 1
ELSE 0
END AS is_late,
CASE
WHEN o.order_delivered_customer_date IS NOT NULL AND o.order_delivered_customer_date > o.order_estimated_delivery_date
THEN ROUND(JULIANDAY(o.order_delivered_customer_date) - JULIANDAY(o.order_estimated_delivery_date), 1)
WHEN o.order_delivered_customer_date IS NULL AND o.order_status NOT IN ('delivered', 'canceled')
THEN ROUND(JULIANDAY('{DEMO_DATE}') - JULIANDAY(o.order_estimated_delivery_date), 1)
ELSE 0
END AS days_overdue
FROM orders o
LEFT JOIN order_items oi ON o.order_id = oi.order_id
LEFT JOIN order_payments p ON o.order_id = p.order_id
GROUP BY o.order_id
""")
# Seller performance view
conn.execute("""
CREATE VIEW IF NOT EXISTS v_seller_summary AS
SELECT
oi.seller_id,
s.seller_city,
s.seller_state,
COUNT(DISTINCT oi.order_id) AS total_orders,
ROUND(AVG(r.review_score), 2) AS avg_rating,
SUM(CASE WHEN r.review_score <= 2 THEN 1 ELSE 0 END) AS negative_reviews,
SUM(CASE WHEN r.review_score >= 4 THEN 1 ELSE 0 END) AS positive_reviews
FROM order_items oi
JOIN sellers s ON oi.seller_id = s.seller_id
LEFT JOIN order_reviews r ON oi.order_id = r.order_id
GROUP BY oi.seller_id
""")
print(" ✓ Views created")
if __name__ == "__main__":
print("Setting up Olist database...")
# Create data directory if it doesn't exist
DB.parent.mkdir(parents=True, exist_ok=True)
conn = sqlite3.connect(DB)
try:
load_tables(conn)
create_indexes(conn)
create_views(conn)
conn.commit()
print(f"\n✅ Database ready at {DB}")
except Exception as e:
print(f"\n❌ Error: {e}")
conn.rollback()
finally:
conn.close()