Sling Academy
Home/SQLAlchemy/SQLAlchemy: Designing an online shopping database schema

SQLAlchemy: Designing an online shopping database schema

Last updated: January 03, 2024

Overview

SQLAlchemy is a powerful ORM library for Python that allows for the rapid design and querying of databases. This tutorial covers the process of creating an online shopping database schema using SQLAlchemy’s latest syntax and features, from basic setup to more advanced model relationships.

Getting Started with SQLAlchemy

To start designing your online shopping database schema, you’ll first need to install SQLAlchemy and a database driver, for instance, for PostgreSQL:

pip install SQLAlchemy psycopg2

Next, establish a connection to your database:

from sqlalchemy import create_engine
engine = create_engine('postgresql+psycopg2://user:password@localhost/dbname')

Now, let’s define the metadata and the base class to keep all model declarations in one place:

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
metadata = Base.metadata

Declaring Models

A basic User model may look like this:

from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import relationship
class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    username = Column(String(50), unique=True, nullable=False)
    email = Column(String(100), unique=True, nullable=False)
    # Relationship to orders
    orders = relationship('Order', back_populates='user')

This User model will be related to Orders. Each order will reference the user that placed it:

class Order(Base):
    __tablename__ = 'orders'
    id = Column(Integer, primary_key=True)
    user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
    # Relationship to user
    user = relationship('User', back_populates='orders')
    # Relationship to order items
    order_items = relationship('OrderItem', back_populates='order')

Within an Order, there may be multiple Items, established by an OrderItem association model:

class OrderItem(Base):
    __tablename__ = 'order_items'
    id = Column(Integer, primary_key=True)
    order_id = Column(Integer, ForeignKey('orders.id'), nullable=False)
    item_id = Column(Integer, ForeignKey('items.id'), nullable=False)
    quantity = Column(Integer, default=1)
    # Relationship to order
    order = relationship('Order', back_populates='order_items')
    # Relationship to items
    item = relationship('Item', back_populates='order_items')

Finally, an Item model representing available products could be defined:

class Item(Base):
    __tablename__ = 'items'
    id = Column(Integer, primary_key=True)
    name = Column(String(255), nullable=False)
    price = Column(Decimal(precision=10, scale=2), nullable=False)
    inventory_count = Column(Integer)
    # Relationship to order items
    order_items = relationship('OrderItem', back_populates='item')

Working with Relationships

SQLAlchemy makes defining complex relationships simpler, such as items having categories:

class Category(Base):
    __tablename__ = 'categories'
    id = Column(Integer, primary_key=True)
    name = Column(String(50), nullable=False)
    # Relationship to category_items
    category_items = relationship('CategoryItem', back_populates='category')
class CategoryItem(Base):
    __tablename__ = 'category_items'
    id = Column(Integer, primary_key=True)
    item_id = Column(Integer, ForeignKey('items.id'), nullable=False)
    category_id = Column(Integer, ForeignKey('categories.id'), nullable=False)
    # Relationships
    item = relationship('Item', back_populates='categories')
    category = relationship('Category', back_populates='items')

Advanced Features

SQLAlchemy also supports advanced features such as database migrations, hybrid properties, and association proxies, which can greatly enhance the robustness of your online shopping schema. Using Alembic for database migrations, for example:

pip install alembic
alembic init migrations

SQLAlchemy is also capable of leveraging Python’s decorators to define hybrid properties that function both as instance attributes and as class-level query expressions:

from sqlalchemy.ext.hybrid import hybrid_method, hybrid_property
class Item(Base):
    __tablename__ = 'items'
    # ... previously defined columns ...
    @hybrid_property
    def is_in_stock(self):
        return self.inventory_count > 0
    @is_in_stock.expression
    def is_in_stock(cls):
        return cls.inventory_count > 0

Conclusively, SQLAlchemy’s versatility facilitates complex operations like transaction management, enforcing the ACID properties, and much more –broadening the horizons of how databases can be handled from within Python code.

Conclusion

This tutorial walked through the essential steps for designing an online shopping database schema using SQLAlchemy’s sophisticated ORM features. By following these guidelines, you will be able to craft an intricate, yet highly manageable database system for any online shopping platform.

Next Article: Exploring One-to-Many Relationships in SQLAlchemy

Previous Article: SQLAlchemy: Designing a Social Network Database Schema

Series: SQLAlchemy Tutorials: From Basic to Advanced

SQLAlchemy

You May Also Like

  • SQLAlchemy: Counting rows for each category (2 approaches)
  • SQLAlchemy: Adding a calculated column to SELECT query
  • SQLAlchemy: Grouping data on multiple columns
  • SQLAlchemy: How to temporarily delete a row
  • SQLAlchemy Composite Indexes: The Complete Guide
  • Full-Text Search in SQLAlchemy: The Ultimate Guide
  • SQLAlchemy: What if you don’t close database connections?
  • SQLAlchemy: How to Remove FOREIGN KEY Constraints (2 Ways)
  • SQLAlchemy: How to Create and Use Temporary Tables
  • SQLAlchemy: Saving Categories and Subcategories in the Same Table
  • SQLAlchemy: How to Automatically Delete Old Records
  • Weighted Random Selection in SQLAlchemy: An In-Depth Guide
  • SQLAlchemy: created_at and updated_at columns
  • How to Use Regular Expressions in SQLAlchemy
  • SQLAlchemy: Ways to Find Results by a Keyword
  • SQLAlchemy: How to Connect to MySQL Database
  • SQLAlchemy: How to Bulk Insert Data into a Table
  • SQLAlchemy: How to Update a Record by ID
  • SQLAlchemy: Singular vs Plural Table Names