DEV Community

Cover image for 📚Enterprise Design Patterns: Table Module with Python Example

📚Enterprise Design Patterns: Table Module with Python Example

🚀 In this article, we’ll explore the Table Module pattern from Martin Fowler’s Catalog of Enterprise Application Architecture.

We’ll break it down with analogies, real-world Python code, and a GitHub repo with automation.


📑 Table of Contents

  1. Why Table Module Matters
  2. What is Table Module?
  3. Analogy: The School Office
  4. Python Example: Orders Table
  5. When to Use & When to Avoid
  6. Curiosities & Recommendations
  7. GitHub Repo + Automation
  8. Final Thoughts

🔥 Why Table Module Matters

In enterprise apps, business logic can live in different places:

  • In the database (stored procedures).
  • In domain models (one class per row).
  • Or in a table module: one class per table.

👉 Table Module keeps all rules for a table in a single place, making code easier to read and maintain when logic is simple.


📖 What is Table Module?

Definition:

A single class that handles the business logic for all rows in a database table or view.

⚖️ Difference with Domain Model:

  • Domain Model → 1 class per row.
  • Table Module → 1 class per table.

🧩 Analogy: The School Office

Imagine a school secretary’s office:

  • Instead of every teacher managing attendance (Domain Model),
  • The office manages attendance records for the whole school (Table Module).

📌 Centralized, consistent, and simple.


💻 Python Example: Orders Table

❌ Without Table Module (spaghetti logic)

import sqlite3 conn = sqlite3.connect(":memory:") cursor = conn.cursor() cursor.execute("CREATE TABLE orders (id INTEGER, customer TEXT, total REAL)") cursor.executemany("INSERT INTO orders VALUES (?, ?, ?)", [ (1, "Alice", 120.0), (2, "Bob", 80.5), (3, "Alice", 45.0) ]) # Logic spread everywhere 😓 cursor.execute("SELECT SUM(total) FROM orders WHERE customer='Alice'") print("Alice total:", cursor.fetchone()[0]) 
Enter fullscreen mode Exit fullscreen mode

❌ Problem: Logic is scattered in SQL queries all over the app.


✅ With Table Module

import sqlite3 class OrdersTable: def __init__(self, connection): self.conn = connection def total_sales(self): cursor = self.conn.cursor() cursor.execute("SELECT SUM(total) FROM orders") return cursor.fetchone()[0] def sales_by_customer(self, customer): cursor = self.conn.cursor() cursor.execute("SELECT SUM(total) FROM orders WHERE customer=?", (customer,)) return cursor.fetchone()[0] # Setup DB conn = sqlite3.connect(":memory:") cursor = conn.cursor() cursor.execute("CREATE TABLE orders (id INTEGER, customer TEXT, total REAL)") cursor.executemany("INSERT INTO orders VALUES (?, ?, ?)", [ (1, "Alice", 120.0), (2, "Bob", 80.5), (3, "Alice", 45.0) ]) # Usage orders = OrdersTable(conn) print("Total Sales:", orders.total_sales()) print("Alice Sales:", orders.sales_by_customer("Alice")) 
Enter fullscreen mode Exit fullscreen mode

SRP: All business logic lives in OrdersTable.

Reusability: Centralized methods.

KISS: Simple & clean.


🤔 When to Use & When to Avoid

✅ Use Table Module when:

  • Business rules are simple.
  • You need reports or aggregations.
  • Tables are the main unit of work.

❌ Avoid when:

  • Each row has complex behavior.
  • You need polymorphism → prefer Domain Model.

🧠 Curiosities & Recommendations

💡 Did you know?

  • Table Module was a stepping stone before modern ORMs like SQLAlchemy or Django ORM.
  • Many legacy apps still hide Table Modules inside stored procedures.
  • Fowler recommends it for reporting systems.

👉 Pro tip: Use Table Module for data-centric apps, Domain Model for behavior-rich apps.


📦 GitHub Repo + Automation

Repo structure:

enterprise-table-module/ ├─ table_module.py ├─ tests/ │ └─ test_table_module.py ├─ requirements.txt └─ .github/ └─ workflows/ └─ ci.yml 
Enter fullscreen mode Exit fullscreen mode

requirements.txt

pytest==8.3.3 
Enter fullscreen mode Exit fullscreen mode

.github/workflows/ci.yml

name: Python CI on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: python-version: '3.11' - run: pip install -r requirements.txt - run: pytest 
Enter fullscreen mode Exit fullscreen mode

🔗 GitHub Repository Example


🎯 Final Thoughts

The Table Module pattern is a powerful yet underrated way to structure enterprise apps when logic is simple and table-oriented.

✨ Remember:

  • Use it for reports and aggregations.
  • Switch to Domain Model when rules grow complex.

✍️ Your turn! Would you use Table Module in your next project?

Let me know in the comments 👇

Top comments (0)