222 lines
9.2 KiB
Python
222 lines
9.2 KiB
Python
import random
|
|
|
|
from faker import Faker
|
|
from faker_commerce import Provider
|
|
|
|
from sqlalchemy import create_engine, Column, Integer, String, Float, ForeignKey, func, asc, desc
|
|
from sqlalchemy.orm import sessionmaker, relationship
|
|
from sqlalchemy.ext.declarative import declarative_base
|
|
|
|
|
|
Base = declarative_base()
|
|
fake = Faker('en_US')
|
|
fake.add_provider(Provider)
|
|
|
|
class Product(Base):
|
|
__tablename__ = 'products'
|
|
id = Column(Integer, primary_key=True)
|
|
name = Column(String, unique=True)
|
|
price = Column(Float)
|
|
category_id = Column(Integer, ForeignKey('categories.id'))
|
|
category = relationship("Category")
|
|
|
|
class Category(Base):
|
|
__tablename__ = 'categories'
|
|
id = Column(Integer, primary_key=True)
|
|
name = Column(String, unique=True)
|
|
|
|
class Supplier(Base):
|
|
__tablename__ = 'suppliers'
|
|
id = Column(Integer, primary_key=True)
|
|
name = Column(String, unique=True)
|
|
rating = Column(Float)
|
|
|
|
class ShippingAddress(Base):
|
|
__tablename__ = 'shipping_addresses'
|
|
id = Column(Integer, primary_key=True)
|
|
address_line_1 = Column(String, unique=True)
|
|
city = Column(String)
|
|
zip_code = Column(String)
|
|
|
|
class Order(Base):
|
|
__tablename__ = 'orders'
|
|
id = Column(Integer, primary_key=True)
|
|
order_date = Column(String)
|
|
total_amount = Column(Float)
|
|
user_id = Column(Integer, ForeignKey('users.id'))
|
|
shipping_address_id = Column(Integer, ForeignKey('shipping_addresses.id'))
|
|
user = relationship("User", back_populates="orders")
|
|
shipping_address = relationship("ShippingAddress")
|
|
|
|
class User(Base):
|
|
__tablename__ = 'users'
|
|
id = Column(Integer, primary_key=True)
|
|
username = Column(String, unique=True)
|
|
account_balance = Column(Float)
|
|
preferred_category_id = Column(Integer, ForeignKey('categories.id'))
|
|
last_ordered_product_id = Column(Integer, ForeignKey('products.id'))
|
|
supplier_rating_id = Column(Integer, ForeignKey('suppliers.id'))
|
|
preferred_category = relationship("Category")
|
|
last_ordered_product = relationship("Product")
|
|
supplier_rating = relationship("Supplier")
|
|
orders = relationship("Order", back_populates="user")
|
|
|
|
engine = create_engine('sqlite:///:memory:')
|
|
Base.metadata.create_all(engine)
|
|
|
|
Session = sessionmaker(bind=engine)
|
|
session = Session()
|
|
|
|
# Add some more sample data with category for Product
|
|
if not session.query(Category).first():
|
|
session.add_all([
|
|
Category(name='Electronics'),
|
|
Category(name='Accessories'),
|
|
Category(name='Books')
|
|
])
|
|
session.commit()
|
|
category_electronics = session.query(Category).filter_by(name='Electronics').first()
|
|
category_accessories = session.query(Category).filter_by(name='Accessories').first()
|
|
category_books = session.query(Category).filter_by(name='Books').first()
|
|
|
|
if not session.query(Product).first():
|
|
session.add_all([
|
|
Product(name='Laptop', price=1200.50, category=category_electronics),
|
|
Product(name='Mouse', price=25.75, category=category_accessories),
|
|
Product(name='Keyboard', price=75.20, category=category_accessories),
|
|
Product(name='Monitor', price=300.00, category=category_electronics),
|
|
Product(name='The Lord of the Rings', price=20.00, category=category_books),
|
|
Product(name='Python Crash Course', price=35.00, category=category_books),
|
|
Product(name='Webcam', price=50.00, category=category_accessories)
|
|
])
|
|
session.commit()
|
|
|
|
if not session.query(User).first():
|
|
session.add_all([
|
|
User(username='Alice', account_balance=500.00, preferred_category_id=1, last_ordered_product_id=1, supplier_rating_id=None),
|
|
User(username='Bob', account_balance=1200.75, preferred_category_id=2, last_ordered_product_id=2, supplier_rating_id=None),
|
|
User(username='Charlie', account_balance=75.50, preferred_category_id=1, last_ordered_product_id=3, supplier_rating_id=None),
|
|
User(username='Diana', account_balance=200.00, preferred_category_id=None, last_ordered_product_id=None, supplier_rating_id=None),
|
|
User(username='Eve', account_balance=1500.00, preferred_category_id=3, last_ordered_product_id=5, supplier_rating_id=None)
|
|
])
|
|
session.commit()
|
|
|
|
if not session.query(Order).first():
|
|
alice = session.query(User).filter_by(username='Alice').first()
|
|
bob = session.query(User).filter_by(username='Bob').first()
|
|
charlie = session.query(User).filter_by(username='Charlie').first()
|
|
shipping_address1 = ShippingAddress(address_line_1='123 Main St', city='Ankara', zip_code='06500')
|
|
shipping_address2 = ShippingAddress(address_line_1='456 Elm Ave', city='Istanbul', zip_code='34000')
|
|
eve = session.query(User).filter_by(username='Eve').first()
|
|
session.add_all([shipping_address1, shipping_address2])
|
|
session.commit()
|
|
session.add_all([
|
|
Order(order_date='2025-05-08', total_amount=1200.50, user=alice, shipping_address=shipping_address1),
|
|
Order(order_date='2025-05-09', total_amount=25.75, user=bob, shipping_address=shipping_address2),
|
|
Order(order_date='2025-05-10', total_amount=75.20, user=charlie, shipping_address=shipping_address1),
|
|
Order(order_date='2025-05-11', total_amount=300.00, user=alice, shipping_address=shipping_address2),
|
|
Order(order_date='2025-05-12', total_amount=20.00, user=eve, shipping_address=shipping_address1),
|
|
Order(order_date='2025-05-13', total_amount=35.00, user=bob, shipping_address=shipping_address2)
|
|
])
|
|
session.commit()
|
|
|
|
# GROUP BY Examples
|
|
|
|
# 1. Count the number of products in each category
|
|
product_counts_by_category = session.query(Category.name, func.count(Product.id)) \
|
|
.join(Product, Product.category_id == Category.id) \
|
|
.group_by(Category.name) \
|
|
.all()
|
|
print("\nProduct Counts by Category:")
|
|
for category, count in product_counts_by_category:
|
|
print(f"Category: {category}, Count: {count}")
|
|
|
|
# 2. Find the average price of products in each category
|
|
average_price_by_category = session.query(Category.name, func.avg(Product.price)) \
|
|
.join(Product, Product.category_id == Category.id) \
|
|
.group_by(Category.name) \
|
|
.all()
|
|
print("\nAverage Price by Category:")
|
|
for category, avg_price in average_price_by_category:
|
|
print(f"Category: {category}, Average Price: {avg_price:.2f}")
|
|
|
|
# 3. Find the maximum order amount for each user
|
|
max_order_amount_by_user = session.query(User.username, func.max(Order.total_amount)) \
|
|
.join(Order, User.id == Order.user_id) \
|
|
.group_by(User.username) \
|
|
.all()
|
|
print("\nMaximum Order Amount by User:")
|
|
for user, max_amount in max_order_amount_by_user:
|
|
print(f"User: {user}, Max Order Amount: {max_amount:.2f}")
|
|
|
|
# ORDER BY Examples
|
|
|
|
# 1. Get all products ordered by price in ascending order
|
|
products_ordered_by_price_asc = session.query(Product.name, Product.price) \
|
|
.order_by(asc(Product.price)) \
|
|
.all()
|
|
print("\nProducts Ordered by Price (Ascending):")
|
|
for name, price in products_ordered_by_price_asc:
|
|
print(f"Product: {name}, Price: {price:.2f}")
|
|
|
|
# 2. Get all users ordered by account balance in descending order
|
|
users_ordered_by_balance_desc = session.query(User.username, User.account_balance) \
|
|
.order_by(desc(User.account_balance)) \
|
|
.all()
|
|
print("\nUsers Ordered by Account Balance (Descending):")
|
|
for username, balance in users_ordered_by_balance_desc:
|
|
print(f"User: {username}, Balance: {balance:.2f}")
|
|
|
|
# 3. Get orders ordered by order date
|
|
orders_ordered_by_date = session.query(Order.id, Order.order_date) \
|
|
.order_by(Order.order_date) \
|
|
.all()
|
|
print("\nOrders Ordered by Date:")
|
|
for order_id, order_date in orders_ordered_by_date:
|
|
print(f"Order ID: {order_id}, Date: {order_date}")
|
|
|
|
# LIMIT Examples
|
|
|
|
# 1. Get the top 3 most expensive products
|
|
top_3_expensive_products = session.query(Product.name, Product.price) \
|
|
.order_by(desc(Product.price)) \
|
|
.limit(3) \
|
|
.all()
|
|
print("\nTop 3 Most Expensive Products:")
|
|
for name, price in top_3_expensive_products:
|
|
print(f"Product: {name}, Price: {price:.2f}")
|
|
|
|
# 2. Get the first 2 users listed alphabetically by username
|
|
first_2_users_alphabetical = session.query(User.username) \
|
|
.order_by(asc(User.username)) \
|
|
.limit(2) \
|
|
.all()
|
|
print("\nFirst 2 Users (Alphabetical):")
|
|
for user in first_2_users_alphabetical:
|
|
print(f"User: {user.username}")
|
|
|
|
# Combining GROUP BY, ORDER BY, and LIMIT
|
|
|
|
# 1. Find the category with the fewest products (limit 1)
|
|
category_with_fewest_products = session.query(Category.name, func.count(Product.id).label('product_count')) \
|
|
.join(Product, Product.category_id == Category.id) \
|
|
.group_by(Category.name) \
|
|
.order_by(asc('product_count')) \
|
|
.limit(1) \
|
|
.first()
|
|
print("\nCategory with Fewest Products:")
|
|
if category_with_fewest_products:
|
|
print(f"Category: {category_with_fewest_products.name}, Count: {category_with_fewest_products.product_count}")
|
|
|
|
# 2. Find the top 2 users with the highest average order amount
|
|
top_2_users_highest_avg_order = session.query(User.username, func.avg(Order.total_amount).label('average_order')) \
|
|
.join(Order, User.id == Order.user_id) \
|
|
.group_by(User.username) \
|
|
.order_by(desc('average_order')) \
|
|
.limit(2) \
|
|
.all()
|
|
print("\nTop 2 Users with Highest Average Order Amount:")
|
|
for user, avg_order in top_2_users_highest_avg_order:
|
|
print(f"User: {user}, Average Order: {avg_order:.2f}")
|
|
|
|
session.close() |