Python

P
PythonHub
Progress 0%

Python

  • Home
  • History of Python
  • Applications of Python
  • Introduction To Python
    • What is Python
    • Character Set
    • Tokens in Python
    • Python Execution Mode
    • Variable And Identifiers
    • Data Types in Python
    • Operators And Expressions
    • Constants in Python
    • Assignment Statement
    • Input / Output in Python
    • Simple Python Scripts
    • Namespace in Python
    • πŸ“ Assignments
  • Operators in Python
    • Arithmetic Operators
    • Assignment Operators
    • Shorthand Assignment Operators
    • Relational Operators
    • Logical Operators
    • Bitwise Operators
    • Special Operators
    • πŸ“ Assignments
  • Input Output in Python
    • Accept Input
    • Output Formatting
    • πŸ“ Assignments
  • Conditional Statement
    • Decision Making
    • if Statement
    • IF-ELSE STATEMENT
    • IF-ELSE LADDER
    • NESTED IF-ELSE
    • Short Hand IF-ELSE
    • πŸ“ Assignments
  • Loops
    • Introduction to Loops
    • While Loop
    • Nested While Loop
    • πŸ“ While Loop Assignments
    • For Loop
    • For Loop Examples
    • Nested For Loop
    • Nested For Loop Examples
    • Infinite While Loops
    • Infinite For Loops
    • Break, Continue and Else in Loops
    • Difference Between For and While Loop
    • For Each Loop
    • πŸ“ For Each Assignments
    • πŸ“ All Loops Assignments
  • List
    • List in Python
    • Access List Elements
    • List Functions
    • Iterate (Loop) List
    • List Comprehension
    • πŸ“ Assignments
  • Tuple
    • Tuple in Python
    • Access Tuple Elements
    • Tuple Functions
    • Iterate (Loop) Tuple
    • Unpack Tuple
    • Tuple Comprehension
    • πŸ“ Assignments
  • Set
    • Set in Python
    • Access Set Elements
    • Set Methods
    • Iterate (Loop) Set
    • Pack/Unpack Set
    • Set Comprehension
    • πŸ“ Assignments
  • Dictionary
    • Dictionary
    • Access Dictionary Items
    • Dictionary Methods
    • Iterate (Loop) Dictionary
    • Formatting Dictionaries
    • Nested Dictionaries
    • Dictionary Comprehension
    • πŸ“ Assignments
  • Diff List Tuple Set Dictionary
    • List vs Tuple
    • List vs Set
    • List vs Dictionary
    • Tuple vs Set
    • Tuple vs Dictionary
    • Dictionary vs Set
    • πŸ“ Assignments
  • Exception
    • Error vs Exception
    • Types of Exception
    • Exception Handling
    • User Defined Exception
    • Logging Exception
    • πŸ“ Assignments
  • Functions
    • Introduction to Functions
    • Modular Programming
    • Types of Functions
    • Inbuilt Functions
    • Need For User-Defined Function
    • Elements of User Defined Function
    • Function Arguments
    • Nesting of Functions
    • Recursion
    • Global Local and Non Local
    • Python Lambda Functions
    • πŸ“ Assignments
  • Python Module
    • Introduction to Module
    • Inbuilt Modules in Python
    • User Defined Module
    • πŸ“ Assignments
  • File Handling
    • Introduction to Files
    • Create File
    • Read Files
    • Write to File
    • Rename File
    • Copy File
    • Move File
    • List Files in Directory
    • Binary Files
    • Zipping and Unzipping Files
    • πŸ“ Assignments
  • Strings
    • Basics of Strings
    • String Special Operators
    • String Formatting Operators
    • String Methods
    • πŸ“ Assignments
  • Regular Expressions
  • Python OOPS
    • Basics of Object Oriented
    • What are Classes and Objects?
    • Creating Class and Object
    • OOP vs Procedural Programming
    • Difference Between Classes and Objects
    • Constructors
    • Destructor
    • Built Class Methods and Attributes
    • Class and Instance Variables
    • Inheritance in Python
    • Single Inheritance
    • Multiple Inheritance
    • Multilevel Inheritance
    • Hierarchical Inheritance
    • Hybrid Inheritance
    • Abstraction
    • Method Overriding
    • Abstract Method
    • Interfaces in Python
    • Abstract Class vs Interface
    • Public, Private and Protected
    • Overloading vs Overriding
    • Inheritance vs Composition
    • Encapsulation
    • Polymorphism
    • Inner Classes
    • πŸ“ Assignments
  • Advanced Python
    • Iterator in Python
    • Generator in Python
    • Decorator in Python
    • Type Hints in Python
    • Async/Await Programming
    • Dataclasses in Python
    • Context Managers in Python
    • Property Decorator in Python
    • __slots__ in Python
    • Enums in Python
    • Walrus Operator in Python
    • Match-Case in Python
    • πŸ“ Assignments
  • Python Standard Library
    • Collections Module
    • Itertools Module
    • Functools Module
    • Datetime Module
    • JSON Module
    • OS Module
    • Sys Module
    • Random Module
    • Math Module
    • πŸ“ Assignments
  • Python Testing
    • Unit Testing in Python
    • Pytest Framework
    • Mocking in Python
    • πŸ“ Assignments
  • Python Best Practices
    • PEP 8 Style Guide
    • Docstrings in Python
    • Logging in Python
    • Code Optimization Tips
    • Debugging Techniques
    • πŸ“ Assignments
  • MySQL Database in Python
    • Introduction to MySQL with Python
    • DBMS vs File System
    • Connecting to MySQL Database
    • Create Database in MySQL
    • Create Table in MySQL
    • Insert Data in MySQL
    • Insert Multiple Rows
    • Select Data from MySQL
    • WHERE Clause in MySQL
    • Update Data in MySQL
    • Delete Data from MySQL
    • Parameterized Queries
    • Transaction Management
    • Error Handling
    • Connection Pooling
    • MySQL Drivers Guide
    • Joins in MySQL
    • Aggregation Functions
    • Backup MySQL Database
    • Best Practices
    • πŸ“ Assignments
  • MySQL Database Operations
    • SELECT Statement
    • MySQL Operators
    • DDL Statements
    • DML Statements
    • Subqueries
    • JOIN Operations
    • Aggregation
    • Case Study
    • πŸ“ Assignments
  • Graphics in Python
  • Threads in Python
    • Introduction to Threads
    • Process vs Threads
    • Concurrent Programming & GIL
    • Uses of Threads
    • Creating Threads
    • Single Tasking
    • Multi Tasking
    • Thread Synchronization
    • πŸ“ Assignments
  • Interview Questions & Answers
  • Python Case Studies
  • Multiple Choice Questions
  • πŸ“ Practice Problems
Get in Touch
  • tech2dsm@gmail.com

© Sankalan Data Tech

Python Language Interactive Tutorial

Python: Complete E-Commerce Case Study

Python MySQL Case Study - Complete E-Commerce Platform

Build a complete E-Commerce platform using Python and MySQL.

Created by Sankalan Data Tech Team Verified
Data Engineers, Analysts, Scientists & Trainers
Created by experienced Python developers, data engineers, and data scientists to make programming easy through practical examples, real-world experience, and clear explanations.
Read Time: 15 minutes Level: Advanced Project: Complete E-Commerce Focus: Real-World Application

Project Overview: In this case study, you'll build a complete E-Commerce platform using Python and MySQL. You'll apply everything you've learned β€” database design, CRUD operations, JOINs, aggregation, and more.

Python Focus: This case study demonstrates how to build a real-world application using mysql-connector-python with all the concepts you've learned.

On this page:
  • Project Overview
  • Database Design
  • Project Setup
  • Data Models
  • CRUD Operations
  • Analytics & Reports
  • Complete Application
  • Best Practices
  • Try It Yourself
  • Quiz
  • FAQ
Share this tutorial:
Twitter LinkedIn Facebook WhatsApp Reddit Telegram Email Copy Link
What You'll Build
  • Complete E-Commerce Platform β€” from database to application
  • Database Design β€” products, customers, orders, reviews
  • CRUD Operations β€” create, read, update, delete
  • Analytics β€” sales reports, customer insights
  • Best Practices β€” security, performance, code organization

Project Overview

We're building a complete E-Commerce platform called "ShopHub". This application will handle:

Product Management

Add, update, search, and list products

Customer Management

Register, login, and manage customers

Order Processing

Create orders, update status, track

Reviews & Ratings

Customer reviews and ratings

Analytics Dashboard

Sales reports, customer insights

Inventory Management

Stock tracking and updates

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ SHOPHUB APPLICATION β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Products β”‚ β”‚ Customers β”‚ β”‚ Orders β”‚ β”‚ β”‚ β”‚ - Add β”‚ β”‚ - Register β”‚ β”‚ - Create β”‚ β”‚ β”‚ β”‚ - Update β”‚ β”‚ - Login β”‚ β”‚ - Update β”‚ β”‚ β”‚ β”‚ - Search β”‚ β”‚ - Profile β”‚ β”‚ - Track β”‚ β”‚ β”‚ β”‚ - Stock β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Reviews β”‚ β”‚ Analytics β”‚ β”‚ Inventory β”‚ β”‚ β”‚ β”‚ - Submit β”‚ β”‚ - Sales β”‚ β”‚ - Stock β”‚ β”‚ β”‚ β”‚ - Ratings β”‚ β”‚ - Reports β”‚ β”‚ - Reorder β”‚ β”‚ β”‚ β”‚ - Comments β”‚ β”‚ - Insights β”‚ β”‚ - Tracking β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ MYSQL DATABASE LAYER β”‚ β”‚ products | customers | orders | reviews β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
1

Project Structure

# ============================================================
# PROJECT STRUCTURE
# ============================================================

shophub/
β”œβ”€β”€ config.py          # Database configuration
β”œβ”€β”€ database.py        # Database connection and pool
β”œβ”€β”€ models/
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ product.py     # Product model
β”‚   β”œβ”€β”€ customer.py    # Customer model
β”‚   β”œβ”€β”€ order.py       # Order model
β”‚   └── review.py      # Review model
β”œβ”€β”€ services/
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ product_service.py
β”‚   β”œβ”€β”€ customer_service.py
β”‚   β”œβ”€β”€ order_service.py
β”‚   └── analytics_service.py
β”œβ”€β”€ utils/
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ logger.py      # Logging
β”‚   └── validators.py  # Input validation
β”œβ”€β”€ main.py            # Application entry point
β”œβ”€β”€ test.py            # Tests
└── requirements.txt   # Dependencies

Key point: A well-organized project structure makes your code maintainable and scalable.

Quick Check: Why is project structure important? (Answer: It makes code maintainable, scalable, and easy to understand)

Database Design

2

E-Commerce Database Schema

# ============================================================
# DATABASE SCHEMA
# ============================================================

# ============================================================
# 1. PRODUCTS TABLE
# ============================================================

CREATE TABLE products (
    product_id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    description TEXT,
    category VARCHAR(50),
    price DECIMAL(10,2) NOT NULL,
    cost DECIMAL(10,2),
    stock_quantity INT DEFAULT 0,
    reorder_level INT DEFAULT 10,
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_category (category),
    INDEX idx_price (price)
);

# ============================================================
# 2. CUSTOMERS TABLE
# ============================================================

CREATE TABLE customers (
    customer_id INT PRIMARY KEY AUTO_INCREMENT,
    first_name VARCHAR(50) NOT NULL,
    last_name VARCHAR(50) NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    phone VARCHAR(15),
    address TEXT,
    city VARCHAR(50),
    state VARCHAR(50),
    zip_code VARCHAR(10),
    country VARCHAR(50) DEFAULT 'India',
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_email (email)
);

# ============================================================
# 3. ORDERS TABLE
# ============================================================

CREATE TABLE orders (
    order_id INT PRIMARY KEY AUTO_INCREMENT,
    customer_id INT NOT NULL,
    order_date DATETIME DEFAULT CURRENT_TIMESTAMP,
    total_amount DECIMAL(10,2) NOT NULL,
    discount_amount DECIMAL(10,2) DEFAULT 0,
    tax_amount DECIMAL(10,2) DEFAULT 0,
    shipping_amount DECIMAL(10,2) DEFAULT 0,
    status VARCHAR(20) DEFAULT 'pending',
    payment_status VARCHAR(20) DEFAULT 'pending',
    shipping_address TEXT,
    tracking_number VARCHAR(50),
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id),
    INDEX idx_customer_id (customer_id),
    INDEX idx_status (status),
    INDEX idx_order_date (order_date)
);

# ============================================================
# 4. ORDER ITEMS TABLE
# ============================================================

CREATE TABLE order_items (
    order_item_id INT PRIMARY KEY AUTO_INCREMENT,
    order_id INT NOT NULL,
    product_id INT NOT NULL,
    quantity INT NOT NULL,
    unit_price DECIMAL(10,2) NOT NULL,
    discount DECIMAL(10,2) DEFAULT 0,
    total_price DECIMAL(10,2) NOT NULL,
    FOREIGN KEY (order_id) REFERENCES orders(order_id),
    FOREIGN KEY (product_id) REFERENCES products(product_id),
    INDEX idx_order_id (order_id),
    INDEX idx_product_id (product_id)
);

# ============================================================
# 5. REVIEWS TABLE
# ============================================================

CREATE TABLE reviews (
    review_id INT PRIMARY KEY AUTO_INCREMENT,
    customer_id INT NOT NULL,
    product_id INT NOT NULL,
    rating INT CHECK (rating >= 1 AND rating <= 5),
    comment TEXT,
    review_date DATE,
    is_verified_purchase BOOLEAN DEFAULT FALSE,
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id),
    FOREIGN KEY (product_id) REFERENCES products(product_id),
    INDEX idx_product_id (product_id),
    INDEX idx_rating (rating)
);

Database design key points:

  • Primary keys β€” unique identifiers for each table
  • Foreign keys β€” relationships between tables
  • Indexes β€” speed up common queries
  • Data types β€” appropriate types for each column

Quick Check: What is the purpose of indexes in a database? (Answer: To speed up queries by making searches faster)

Project Setup

3

Setting Up the Project

# ============================================================
# config.py - Configuration
# ============================================================

import os
from dotenv import load_dotenv

load_dotenv()

class Config:
    """Application configuration"""
    
    # Database configuration
    DB_HOST = os.getenv('DB_HOST', 'localhost')
    DB_USER = os.getenv('DB_USER', 'root')
    DB_PASSWORD = os.getenv('DB_PASSWORD', 'secret')
    DB_NAME = os.getenv('DB_NAME', 'shophub_db')
    DB_POOL_SIZE = int(os.getenv('DB_POOL_SIZE', '10'))
    
    # Application settings
    DEBUG = os.getenv('DEBUG', 'True').lower() == 'true'
    LOG_LEVEL = os.getenv('LOG_LEVEL', 'INFO')
    
    @classmethod
    def get_db_config(cls):
        """Get database connection configuration"""
        return {
            'host': cls.DB_HOST,
            'user': cls.DB_USER,
            'password': cls.DB_PASSWORD,
            'database': cls.DB_NAME,
            'pool_name': 'shophub_pool',
            'pool_size': cls.DB_POOL_SIZE,
            'pool_reset_session': True
        }

# ============================================================
# database.py - Database Connection
# ============================================================

import mysql.connector
from mysql.connector import pooling
import logging

logger = logging.getLogger(__name__)

class Database:
    """Database connection management"""
    
    _instance = None
    
    def __new__(cls, config):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._instance._initialize(config)
        return cls._instance
    
    def _initialize(self, config):
        """Initialize connection pool"""
        try:
            self.pool = mysql.connector.pooling.MySQLConnectionPool(**config)
            logger.info(f"Database pool created: {self.pool.pool_name} (size: {self.pool.pool_size})")
        except Exception as e:
            logger.error(f"Failed to create pool: {e}")
            raise
    
    def get_connection(self):
        """Get a connection from the pool"""
        try:
            return self.pool.get_connection()
        except Exception as e:
            logger.error(f"Failed to get connection: {e}")
            raise
    
    def execute_query(self, query, params=None, fetch_all=True):
        """Execute a query and return results"""
        connection = None
        cursor = None
        
        try:
            connection = self.get_connection()
            cursor = connection.cursor()
            
            if params:
                cursor.execute(query, params)
            else:
                cursor.execute(query)
            
            if query.strip().upper().startswith('SELECT'):
                return cursor.fetchall() if fetch_all else cursor.fetchone()
            else:
                connection.commit()
                return cursor.rowcount
                
        except Exception as e:
            if connection:
                connection.rollback()
            logger.error(f"Query failed: {e}")
            raise
            
        finally:
            if cursor:
                cursor.close()
            if connection:
                connection.close()

Setup key points:

  • Environment variables β€” keep credentials secure
  • Connection pooling β€” efficient database access
  • Singleton pattern β€” one pool per application
  • Error handling β€” robust error management

Quick Check: Why use environment variables for credentials? (Answer: To keep passwords out of source code for security)

Data Models

4

Building the Data Models

# ============================================================
# models/product.py - Product Model
# ============================================================

from datetime import datetime

class Product:
    """Product model with database operations"""
    
    def __init__(self, db):
        self.db = db
    
    def create(self, name, description, category, price, cost=None, stock=0):
        """Create a new product"""
        query = """
            INSERT INTO products (name, description, category, price, cost, stock_quantity)
            VALUES (%s, %s, %s, %s, %s, %s)
        """
        params = (name, description, category, price, cost, stock)
        return self.db.execute_query(query, params)
    
    def get_by_id(self, product_id):
        """Get product by ID"""
        query = "SELECT * FROM products WHERE product_id = %s"
        return self.db.execute_query(query, (product_id,), fetch_all=False)
    
    def get_all(self, limit=100, offset=0):
        """Get all products with pagination"""
        query = "SELECT * FROM products LIMIT %s OFFSET %s"
        return self.db.execute_query(query, (limit, offset))
    
    def get_by_category(self, category, limit=100):
        """Get products by category"""
        query = """
            SELECT * FROM products 
            WHERE category = %s AND is_active = TRUE
            LIMIT %s
        """
        return self.db.execute_query(query, (category, limit))
    
    def search(self, search_term, limit=50):
        """Search products by name or description"""
        query = """
            SELECT * FROM products 
            WHERE name LIKE %s OR description LIKE %s
            AND is_active = TRUE
            LIMIT %s
        """
        pattern = f"%{search_term}%"
        return self.db.execute_query(query, (pattern, pattern, limit))
    
    def update(self, product_id, **kwargs):
        """Update product fields"""
        fields = []
        params = []
        
        for key, value in kwargs.items():
            if value is not None:
                fields.append(f"{key} = %s")
                params.append(value)
        
        if not fields:
            return 0
        
        params.append(product_id)
        query = f"""
            UPDATE products 
            SET {', '.join(fields)}
            WHERE product_id = %s
        """
        return self.db.execute_query(query, params)
    
    def update_stock(self, product_id, quantity_change):
        """Update product stock"""
        query = """
            UPDATE products 
            SET stock_quantity = stock_quantity + %s 
            WHERE product_id = %s 
            AND stock_quantity + %s >= 0
        """
        return self.db.execute_query(query, (quantity_change, product_id, quantity_change))
    
    def delete(self, product_id):
        """Soft delete a product"""
        return self.update(product_id, is_active=False)
    
    def get_low_stock(self, threshold=10):
        """Get products with low stock"""
        query = """
            SELECT * FROM products 
            WHERE stock_quantity <= %s AND is_active = TRUE
        """
        return self.db.execute_query(query, (threshold,))
    
    def get_top_selling(self, limit=10):
        """Get top selling products"""
        query = """
            SELECT p.product_id, p.name, p.price, 
                   COALESCE(SUM(oi.quantity), 0) AS total_sold,
                   COALESCE(SUM(oi.quantity * oi.unit_price), 0) AS revenue
            FROM products p
            LEFT JOIN order_items oi ON p.product_id = oi.product_id
            GROUP BY p.product_id
            ORDER BY total_sold DESC
            LIMIT %s
        """
        return self.db.execute_query(query, (limit,))

# ============================================================
# models/customer.py - Customer Model
# ============================================================

import bcrypt

class Customer:
    """Customer model with database operations"""
    
    def __init__(self, db):
        self.db = db
    
    def _hash_password(self, password):
        """Hash a password"""
        salt = bcrypt.gensalt()
        return bcrypt.hashpw(password.encode(), salt)
    
    def _verify_password(self, password, hashed):
        """Verify a password"""
        return bcrypt.checkpw(password.encode(), hashed)
    
    def create(self, first_name, last_name, email, password, phone=None, address=None):
        """Create a new customer"""
        hashed = self._hash_password(password)
        query = """
            INSERT INTO customers (first_name, last_name, email, password_hash, phone, address)
            VALUES (%s, %s, %s, %s, %s, %s)
        """
        params = (first_name, last_name, email, hashed, phone, address)
        return self.db.execute_query(query, params)
    
    def get_by_id(self, customer_id):
        """Get customer by ID"""
        query = "SELECT * FROM customers WHERE customer_id = %s"
        return self.db.execute_query(query, (customer_id,), fetch_all=False)
    
    def get_by_email(self, email):
        """Get customer by email"""
        query = "SELECT * FROM customers WHERE email = %s"
        return self.db.execute_query(query, (email,), fetch_all=False)
    
    def authenticate(self, email, password):
        """Authenticate a customer"""
        customer = self.get_by_email(email)
        if not customer:
            return None
        if self._verify_password(password, customer[4]):  # password_hash is at index 4
            return customer
        return None
    
    def update(self, customer_id, **kwargs):
        """Update customer fields"""
        fields = []
        params = []
        
        for key, value in kwargs.items():
            if value is not None:
                if key == 'password':
                    fields.append("password_hash = %s")
                    params.append(self._hash_password(value))
                else:
                    fields.append(f"{key} = %s")
                    params.append(value)
        
        if not fields:
            return 0
        
        params.append(customer_id)
        query = f"""
            UPDATE customers 
            SET {', '.join(fields)}
            WHERE customer_id = %s
        """
        return self.db.execute_query(query, params)
    
    def get_orders(self, customer_id):
        """Get all orders for a customer"""
        query = """
            SELECT * FROM orders 
            WHERE customer_id = %s 
            ORDER BY order_date DESC
        """
        return self.db.execute_query(query, (customer_id,))
    
    def get_spending_summary(self, customer_id):
        """Get spending summary for a customer"""
        query = """
            SELECT 
                COUNT(order_id) AS order_count,
                COALESCE(SUM(total_amount), 0) AS total_spent,
                COALESCE(AVG(total_amount), 0) AS avg_order_value
            FROM orders
            WHERE customer_id = %s AND status = 'completed'
        """
        return self.db.execute_query(query, (customer_id,), fetch_all=False)

Models key points:

  • Encapsulation β€” database operations in model classes
  • Password hashing β€” secure password storage
  • CRUD operations β€” create, read, update, delete
  • Business logic β€” authentication, stock management

Quick Check: Why is password hashing important? (Answer: To protect user passwords even if the database is compromised)

CRUD Operations

5

Complete CRUD Implementation

# ============================================================
# services/product_service.py - Product Service
# ============================================================

import logging

logger = logging.getLogger(__name__)

class ProductService:
    """Product service with business logic"""
    
    def __init__(self, product_model):
        self.product = product_model
    
    def add_product(self, name, description, category, price, cost=None, stock=0):
        """Add a new product with validation"""
        # Validate inputs
        if not name or len(name) < 2:
            return {"success": False, "error": "Product name must be at least 2 characters"}
        
        if price <= 0:
            return {"success": False, "error": "Price must be greater than 0"}
        
        if stock < 0:
            return {"success": False, "error": "Stock cannot be negative"}
        
        try:
            product_id = self.product.create(name, description, category, price, cost, stock)
            logger.info(f"Product added: {name} (ID: {product_id})")
            return {"success": True, "product_id": product_id, "message": "Product added successfully"}
        except Exception as e:
            logger.error(f"Failed to add product: {e}")
            return {"success": False, "error": str(e)}
    
    def get_product(self, product_id):
        """Get a product by ID"""
        try:
            product = self.product.get_by_id(product_id)
            if not product:
                return {"success": False, "error": "Product not found"}
            return {"success": True, "product": product}
        except Exception as e:
            logger.error(f"Failed to get product: {e}")
            return {"success": False, "error": str(e)}
    
    def update_product(self, product_id, **kwargs):
        """Update a product"""
        try:
            # Check if product exists
            existing = self.product.get_by_id(product_id)
            if not existing:
                return {"success": False, "error": "Product not found"}
            
            # Validate price if provided
            if 'price' in kwargs and kwargs['price'] <= 0:
                return {"success": False, "error": "Price must be greater than 0"}
            
            rows = self.product.update(product_id, **kwargs)
            if rows > 0:
                logger.info(f"Product {product_id} updated")
                return {"success": True, "message": "Product updated successfully"}
            return {"success": False, "error": "No changes made"}
        except Exception as e:
            logger.error(f"Failed to update product: {e}")
            return {"success": False, "error": str(e)}
    
    def search_products(self, search_term, limit=50):
        """Search for products"""
        try:
            results = self.product.search(search_term, limit)
            return {"success": True, "products": results, "count": len(results)}
        except Exception as e:
            logger.error(f"Search failed: {e}")
            return {"success": False, "error": str(e)}
    
    def get_low_stock_alert(self, threshold=10):
        """Get products that need reordering"""
        try:
            products = self.product.get_low_stock(threshold)
            return {"success": True, "products": products, "count": len(products)}
        except Exception as e:
            logger.error(f"Failed to get low stock: {e}")
            return {"success": False, "error": str(e)}
    
    def update_stock(self, product_id, quantity_change):
        """Update product stock"""
        try:
            rows = self.product.update_stock(product_id, quantity_change)
            if rows > 0:
                return {"success": True, "message": f"Stock updated by {quantity_change}"}
            return {"success": False, "error": "Insufficient stock or product not found"}
        except Exception as e:
            logger.error(f"Failed to update stock: {e}")
            return {"success": False, "error": str(e)}

# ============================================================
# services/customer_service.py - Customer Service
# ============================================================

class CustomerService:
    """Customer service with business logic"""
    
    def __init__(self, customer_model):
        self.customer = customer_model
    
    def register(self, first_name, last_name, email, password, phone=None, address=None):
        """Register a new customer"""
        # Validate inputs
        if not first_name or len(first_name) < 2:
            return {"success": False, "error": "First name must be at least 2 characters"}
        
        if not last_name or len(last_name) < 2:
            return {"success": False, "error": "Last name must be at least 2 characters"}
        
        if not email or '@' not in email:
            return {"success": False, "error": "Valid email is required"}
        
        if not password or len(password) < 6:
            return {"success": False, "error": "Password must be at least 6 characters"}
        
        # Check if email exists
        existing = self.customer.get_by_email(email)
        if existing:
            return {"success": False, "error": "Email already registered"}
        
        try:
            customer_id = self.customer.create(first_name, last_name, email, password, phone, address)
            logger.info(f"Customer registered: {email} (ID: {customer_id})")
            return {"success": True, "customer_id": customer_id, "message": "Registration successful"}
        except Exception as e:
            logger.error(f"Registration failed: {e}")
            return {"success": False, "error": str(e)}
    
    def login(self, email, password):
        """Login a customer"""
        try:
            customer = self.customer.authenticate(email, password)
            if customer:
                logger.info(f"Customer logged in: {email}")
                return {"success": True, "customer": customer}
            return {"success": False, "error": "Invalid email or password"}
        except Exception as e:
            logger.error(f"Login failed: {e}")
            return {"success": False, "error": str(e)}
    
    def get_profile(self, customer_id):
        """Get customer profile"""
        try:
            customer = self.customer.get_by_id(customer_id)
            if not customer:
                return {"success": False, "error": "Customer not found"}
            
            # Get spending summary
            summary = self.customer.get_spending_summary(customer_id)
            
            return {
                "success": True,
                "customer": customer,
                "summary": summary
            }
        except Exception as e:
            logger.error(f"Failed to get profile: {e}")
            return {"success": False, "error": str(e)}
    
    def update_profile(self, customer_id, **kwargs):
        """Update customer profile"""
        try:
            rows = self.customer.update(customer_id, **kwargs)
            if rows > 0:
                return {"success": True, "message": "Profile updated successfully"}
            return {"success": False, "error": "No changes made"}
        except Exception as e:
            logger.error(f"Failed to update profile: {e}")
            return {"success": False, "error": str(e)}

CRUD operations key points:

  • Validation β€” validate inputs before database operations
  • Error handling β€” comprehensive error handling
  • Logging β€” track operations for debugging
  • Return values β€” consistent response format

Quick Check: Why is input validation important? (Answer: To prevent errors and security issues)

Analytics & Reports

6

Sales Analytics and Reporting

# ============================================================
# services/analytics_service.py - Analytics Service
# ============================================================

import logging
from datetime import datetime, timedelta

logger = logging.getLogger(__name__)

class AnalyticsService:
    """Analytics and reporting service"""
    
    def __init__(self, db):
        self.db = db
    
    def get_dashboard_metrics(self):
        """Get dashboard metrics"""
        query = """
            SELECT 
                (SELECT COUNT(*) FROM customers) AS total_customers,
                (SELECT COUNT(*) FROM products WHERE stock_quantity > 0) AS products_in_stock,
                (SELECT COUNT(*) FROM orders WHERE status = 'pending') AS pending_orders,
                (SELECT COALESCE(SUM(total_amount), 0) FROM orders WHERE status = 'completed') AS total_revenue,
                (SELECT COALESCE(AVG(total_amount), 0) FROM orders WHERE status = 'completed') AS avg_order_value,
                (SELECT COUNT(*) FROM orders WHERE status = 'completed') AS completed_orders
        """
        return self.db.execute_query(query, fetch_all=False)
    
    def get_sales_by_category(self, start_date=None, end_date=None):
        """Get sales by category"""
        conditions = ["o.status = 'completed'"]
        params = []
        
        if start_date:
            conditions.append("o.order_date >= %s")
            params.append(start_date)
        if end_date:
            conditions.append("o.order_date <= %s")
            params.append(end_date)
        
        where_clause = " AND ".join(conditions)
        query = f"""
            SELECT p.category,
                   COUNT(DISTINCT o.order_id) AS order_count,
                   SUM(oi.quantity) AS units_sold,
                   SUM(oi.quantity * oi.unit_price) AS revenue
            FROM products p
            JOIN order_items oi ON p.product_id = oi.product_id
            JOIN orders o ON oi.order_id = o.order_id
            WHERE {where_clause}
            GROUP BY p.category
            ORDER BY revenue DESC
        """
        return self.db.execute_query(query, params)
    
    def get_monthly_revenue(self, months=6):
        """Get monthly revenue for last N months"""
        query = """
            SELECT DATE_FORMAT(order_date, '%Y-%m') AS month,
                   COUNT(order_id) AS order_count,
                   SUM(total_amount) AS revenue,
                   AVG(total_amount) AS avg_order
            FROM orders
            WHERE status = 'completed'
            AND order_date >= DATE_SUB(CURDATE(), INTERVAL %s MONTH)
            GROUP BY DATE_FORMAT(order_date, '%Y-%m')
            ORDER BY month DESC
        """
        return self.db.execute_query(query, (months,))
    
    def get_top_products(self, limit=10, period='all'):
        """Get top selling products"""
        date_filter = ""
        params = [limit]
        
        if period == 'month':
            date_filter = "AND o.order_date >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)"
        elif period == 'quarter':
            date_filter = "AND o.order_date >= DATE_SUB(CURDATE(), INTERVAL 90 DAY)"
        
        query = f"""
            SELECT p.product_id, p.name, p.category,
                   COALESCE(SUM(oi.quantity), 0) AS total_sold,
                   COALESCE(SUM(oi.quantity * oi.unit_price), 0) AS revenue
            FROM products p
            LEFT JOIN order_items oi ON p.product_id = oi.product_id
            LEFT JOIN orders o ON oi.order_id = o.order_id
            WHERE o.status = 'completed' OR o.status IS NULL {date_filter}
            GROUP BY p.product_id
            ORDER BY total_sold DESC
            LIMIT %s
        """
        return self.db.execute_query(query, params)
    
    def get_customer_analytics(self):
        """Get customer analytics"""
        query = """
            SELECT 
                COUNT(DISTINCT customer_id) AS total_customers,
                (SELECT COUNT(DISTINCT customer_id) FROM orders) AS customers_with_orders,
                COALESCE(AVG(order_count), 0) AS avg_orders_per_customer,
                COALESCE(AVG(total_spent), 0) AS avg_spent_per_customer
            FROM (
                SELECT c.customer_id,
                       COUNT(o.order_id) AS order_count,
                       COALESCE(SUM(o.total_amount), 0) AS total_spent
                FROM customers c
                LEFT JOIN orders o ON c.customer_id = o.customer_id
                GROUP BY c.customer_id
            ) AS customer_stats
        """
        return self.db.execute_query(query, fetch_all=False)
    
    def get_order_summary(self, status=None):
        """Get order summary by status"""
        conditions = []
        params = []
        
        if status:
            conditions.append("status = %s")
            params.append(status)
        
        where_clause = " AND ".join(conditions) if conditions else "1=1"
        
        query = f"""
            SELECT status,
                   COUNT(*) AS order_count,
                   COALESCE(SUM(total_amount), 0) AS total_value,
                   COALESCE(AVG(total_amount), 0) AS avg_value
            FROM orders
            WHERE {where_clause}
            GROUP BY status
            ORDER BY status
        """
        return self.db.execute_query(query, params)
    
    def get_recent_orders(self, limit=10):
        """Get recent orders with customer names"""
        query = """
            SELECT o.order_id, o.order_date, o.total_amount, o.status,
                   c.first_name, c.last_name, c.email
            FROM orders o
            JOIN customers c ON o.customer_id = c.customer_id
            ORDER BY o.order_date DESC
            LIMIT %s
        """
        return self.db.execute_query(query, (limit,))
    
    def generate_report(self, report_type):
        """Generate different types of reports"""
        reports = {
            'dashboard': self.get_dashboard_metrics,
            'sales_by_category': self.get_sales_by_category,
            'top_products': self.get_top_products,
            'customer_analytics': self.get_customer_analytics,
            'order_summary': self.get_order_summary,
            'recent_orders': self.get_recent_orders
        }
        
        if report_type in reports:
            return reports[report_type]()
        return {"error": "Invalid report type"}

Analytics key points:

  • Dashboard metrics β€” key performance indicators
  • Sales reports β€” by category, time period
  • Customer analytics β€” spending patterns
  • Order summary β€” status distribution

Quick Check: What are dashboard metrics? (Answer: Key performance indicators like total revenue, order count, customer count)

Complete Application

7

Putting It All Together

# ============================================================
# main.py - Application Entry Point
# ============================================================

import logging
import sys
from datetime import datetime

from config import Config
from database import Database
from models.product import Product
from models.customer import Customer
from services.product_service import ProductService
from services.customer_service import CustomerService
from services.analytics_service import AnalyticsService

# Set up logging
logging.basicConfig(
    level=Config.LOG_LEVEL,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

class ShopHubApplication:
    """Main application class"""
    
    def __init__(self):
        self.db = Database(Config.get_db_config())
        self.product_model = Product(self.db)
        self.customer_model = Customer(self.db)
        self.product_service = ProductService(self.product_model)
        self.customer_service = CustomerService(self.customer_model)
        self.analytics = AnalyticsService(self.db)
        logger.info("Application initialized")
    
    def run_demo(self):
        """Run demonstration of all features"""
        print("\n" + "=" * 60)
        print("SHOPHUB E-COMMERCE PLATFORM - DEMONSTRATION")
        print("=" * 60)
        
        # ============================================================
        # 1. PRODUCT MANAGEMENT
        # ============================================================
        print("\n1. PRODUCT MANAGEMENT")
        print("-" * 40)
        
        # Add products
        print("\nAdding products...")
        self.product_service.add_product(
            "iPhone 15 Pro", 
            "Latest Apple smartphone with advanced features",
            "Electronics", 999.99, 800.00, 50
        )
        self.product_service.add_product(
            "MacBook Air M3",
            "Lightweight laptop with M3 chip",
            "Electronics", 1099.99, 900.00, 20
        )
        self.product_service.add_product(
            "Nike Air Max 270",
            "Comfortable running shoes",
            "Footwear", 149.99, 100.00, 100
        )
        
        # Search products
        print("\nSearching for 'iPhone'...")
        result = self.product_service.search_products("iPhone")
        if result['success']:
            print(f"Found {result['count']} products")
        
        # ============================================================
        # 2. CUSTOMER MANAGEMENT
        # ============================================================
        print("\n2. CUSTOMER MANAGEMENT")
        print("-" * 40)
        
        # Register customers
        print("\nRegistering customers...")
        self.customer_service.register("Rahul", "Sharma", "rahul@email.com", "password123")
        self.customer_service.register("Priya", "Patel", "priya@email.com", "secure456")
        self.customer_service.register("Amit", "Singh", "amit@email.com", "mypassword")
        
        # Login
        print("\nLogging in...")
        result = self.customer_service.login("rahul@email.com", "password123")
        if result['success']:
            print(f"Welcome back, {result['customer'][1]}!")
        
        # ============================================================
        # 3. ANALYTICS DASHBOARD
        # ============================================================
        print("\n3. ANALYTICS DASHBOARD")
        print("-" * 40)
        
        # Dashboard metrics
        metrics = self.analytics.get_dashboard_metrics()
        if metrics:
            print(f"\nTotal Customers: {metrics[0]}")
            print(f"Products in Stock: {metrics[1]}")
            print(f"Pending Orders: {metrics[2]}")
            print(f"Total Revenue: ${metrics[3]:.2f}")
            print(f"Average Order Value: ${metrics[4]:.2f}")
        
        # ============================================================
        # 4. SUMMARY
        # ============================================================
        print("\n4. SUMMARY")
        print("-" * 40)
        print("""
βœ… Product Management - Add, search, update products
βœ… Customer Management - Register, login, authenticate
βœ… Analytics Dashboard - Sales metrics, customer insights
βœ… E-Commerce Platform - Complete working application
        """)
        
        print("\nApplication demonstration complete!")

def main():
    """Application entry point"""
    try:
        app = ShopHubApplication()
        app.run_demo()
    except Exception as e:
        logger.error(f"Application failed: {e}")
        sys.exit(1)

if __name__ == "__main__":
    main()

Complete application key points:

  • Modular design β€” separate concerns
  • Dependency injection β€” pass dependencies
  • Comprehensive demo β€” shows all features
  • Error handling β€” robust error management

Quick Check: What makes this application production-ready? (Answer: Modular design, error handling, logging, and secure practices)

Best Practices Applied

8

Best Practices in This Case Study

# ============================================================
# BEST PRACTICES APPLIED
# ============================================================

print("1. SECURITY")
print("   βœ… Parameterized queries (SQL injection prevention)")
print("   βœ… Password hashing (bcrypt)")
print("   βœ… Environment variables for credentials")
print("   βœ… Input validation")

print("\n2. PERFORMANCE")
print("   βœ… Connection pooling")
print("   βœ… Indexes on common query columns")
print("   βœ… LIMIT for pagination")
print("   βœ… Specific column selection")

print("\n3. CODE ORGANIZATION")
print("   βœ… MVC-like structure")
print("   βœ… Separation of concerns")
print("   βœ… Dependency injection")
print("   βœ… Logging")

print("\n4. DATABASE DESIGN")
print("   βœ… Normalized schema")
print("   βœ… Foreign keys for integrity")
print("   βœ… Indexes for performance")
print("   βœ… Soft delete support")

print("\n5. ERROR HANDLING")
print("   βœ… Comprehensive try/except")
print("   βœ… User-friendly error messages")
print("   βœ… Logging for debugging")
print("   βœ… Transaction management")

print("\n6. SCALABILITY")
print("   βœ… Connection pooling")
print("   βœ… Pagination support")
print("   βœ… Reusable services")
print("   βœ… Configurable settings")

Best practices summary:

  • Security β€” parameterized queries, password hashing
  • Performance β€” connection pooling, indexes
  • Code organization β€” MVC structure, separation of concerns
  • Error handling β€” comprehensive try/except, logging
  • Scalability β€” pagination, reusable services

Quick Check: What is the most important security practice applied? (Answer: Parameterized queries to prevent SQL injection)

Try It Yourself

See the complete E-Commerce application in action below.

Loading Pyodide... 0%
Python Code Editor
========================================
SHOPHUB E-COMMERCE - DEMO
========================================

1. ADDING PRODUCTS
----------------------------------------
Added product: iPhone 15 Pro (ID: 1)
Added product: MacBook Air M3 (ID: 2)
Added product: Nike Air Max (ID: 3)

2. REGISTERING CUSTOMERS
----------------------------------------
Registered customer: Rahul Sharma (ID: 1)
Registered customer: Priya Patel (ID: 2)

3. CREATING ORDERS
----------------------------------------
Order 1 created: iPhone 15 Pro, MacBook Air M3 - Total: $2099.98
Order 2 created: Nike Air Max - Total: $149.99
Order 3 created: Nike Air Max - Total: $149.99

4. DASHBOARD
----------------------------------------

========================================
DASHBOARD
========================================
Products: 3
Customers: 2
Orders: 3
Total Revenue: $2399.96

5. APPLICATION SUMMARY
----------------------------------------
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Feature β”‚ Status β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Product Mgmt β”‚ Add, list, search products β”‚
β”‚ Customer Mgmt β”‚ Register, login customers β”‚
β”‚ Order Processingβ”‚ Create orders, update stock β”‚
β”‚ Analytics β”‚ Dashboard, sales reports β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Complete E-Commerce application built with Python and MySQL!
πŸ†

You've Got It!

You've built a complete E-Commerce platform using Python and MySQL. You've applied all the concepts from this tutorial series!

Quick Quiz

Test what you've learned:

1. What is the purpose of a foreign key?
2. What does connection pooling do?
3. What is the purpose of password hashing?
4. What is a singleton pattern?
5. What is the purpose of the HAVING clause?

Frequently Asked Questions

What is the difference between a service and a model? β–Ό

Models handle database operations (CRUD). Services handle business logic, validation, and orchestrate multiple models. Services call models to perform database operations.

Why use environment variables for configuration? β–Ό

Environment variables keep sensitive information like passwords out of source code. They also make it easy to change configuration between environments (development, staging, production).

What is a common interview question about this case study? β–Ό

Common questions include: "How would you design an E-Commerce database?" "Explain the difference between models and services" and "How do you handle authentication securely?"

How can I deploy this application? β–Ό

You can deploy this application as a web API using Flask or Django. The database layer can be connected to a cloud database like AWS RDS or Azure Database for MySQL. Follow standard deployment practices for Python applications.

Will this conflict with future pure MySQL tutorials? β–Ό

No. This case study focuses on building a complete application using Python with all the concepts you've learned. Future MySQL tutorials will focus on pure SQL concepts with different titles and URLs.

Where to Go From Here

Congratulations on completing this case study! Here are some next steps:

Practice Assignments

Test your knowledge with practical exercises.

Practice Now β†’

Review: Connecting to MySQL

Refresh your connection management skills.

Review β†’

Best Practices

Review all best practices for MySQL in Python.

Review β†’
Interview Resources
  • Python Syntax & Variables Interview Questions
  • Top SQL Interview Questions & Answers
  • SQL Joins: Displaying Data from Multiple Tables FAQ
  • Python Lists and Dictionaries Interview Questions
  • Python OOP Interview Questions
  • SQL Set Operators Interview Questions
Previous: Aggregation Next: Assignments β†’