# How Database Schema Changes Are Managed in Mini-Shop Server (Without Flask-Migrate)

> Learn how mini-shop-server manages database schema changes without Flask-Migrate using db.create_all() and Python scripts for efficient updates.

- Repository: [A粒麦子/mini-shop-server](https://github.com/allen7d/mini-shop-server)
- Tags: how-to-guide
- Published: 2026-02-24

---

**The mini-shop-server repository handles database schema changes manually using Flask-SQLAlchemy's `db.create_all()` method rather than Flask-Migrate, requiring developers to update model classes and synchronize the database through Python scripts or raw SQL dumps.**

Managing database schema changes is a critical aspect of any Flask application. While many Python projects rely on Flask-Migrate (Alembic) for version-controlled migrations, the `allen7d/mini-shop-server` takes a different approach. This article examines how schema evolution works in this codebase, from local development to production deployment.

## Why Flask-Migrate Is Not Used

The project intentionally omits Flask-Migrate from its dependency stack. Examining [`pyproject.toml`](https://github.com/allen7d/mini-shop-server/blob/main/pyproject.toml) reveals only **Flask-SQLAlchemy** as the database layer, without Alembic or Flask-Migrate packages. Consequently, no `migrations/` directory exists in the repository, and the team relies on a **model-first → manual synchronization** workflow instead of versioned migration scripts.

## How Database Schema Changes Work in Mini-Shop Server

Schema management follows a three-step manual process that requires careful coordination between code changes and database state.

### Step 1: Define or Update Models in `app/models/`

Every database table is declared as a Python class inheriting from `EntityModel` (or `BaseModel`) within the `app/models/` package. To change the schema, developers modify these class definitions directly.

```python

# app/models/user.py

class User(EntityModel):
    username = Column(String(64), unique=True, comment='登录用户名')
    password = Column(String(128), comment='密码哈希')
    email = Column(String(100), comment='邮箱')  # New column added

```

### Step 2: Synchronize with `db.create_all()`

After modifying models, developers synchronize the database by invoking `db.create_all()` within an application context. This method creates missing tables and columns but does not alter or drop existing columns (non-destructive update).

```python

# server.py (entry point)

from app.core.db import db

db.init_app(app)

with app.app_context():
    db.create_all()  # Creates new tables/columns only

```

For destructive changes (renaming or dropping columns), developers must manually execute `db.drop_all()` followed by `db.create_all()`, which destroys all data, or use raw SQL scripts.

### Step 3: Production Deployment via SQL Scripts

For production environments, the repository provides a raw SQL dump file named [`zerd.sql`](https://github.com/allen7d/mini-shop-server/blob/main/zerd.sql). When schema changes are required, the team updates this dump manually and applies it using standard MySQL client tools rather than Python migration commands.

```bash

# Export current schema for version control

mysqldump -u root -p mini_shop > zerd.sql

# Apply updated schema to production

mysql -u root -p mini_shop < zerd.sql

```

## Key Files Involved in Schema Management

- **[`app/core/db.py`](https://github.com/allen7d/mini-shop-server/blob/main/app/core/db.py)** — Central SQLAlchemy wrapper containing the `db` instance, custom `Query` class, and `Pagination` logic used across all models.
- **`app/models/*.py`** — Directory containing all table definitions (e.g., `User`, `Product`, `Order`), each inheriting from `EntityModel`.
- **[`server.py`](https://github.com/allen7d/mini-shop-server/blob/main/server.py)** — Application entry point that initializes the database extension and optionally calls `db.create_all()` during startup.
- **[`zerd.sql`](https://github.com/allen7d/mini-shop-server/blob/main/zerd.sql)** — Raw SQL dump used for manual schema synchronization in production environments.

## Practical Example: Adding a New Column

To add a `stock` column to the `Product` table:

1. **Modify the model** in [`app/models/product.py`](https://github.com/allen7d/mini-shop-server/blob/main/app/models/product.py):

```python
class Product(EntityModel):
    name = Column(String(128), comment='商品名称')
    price = Column(Integer, comment='商品价格（分）')
    stock = Column(Integer, default=0, comment='库存数量')  # New column

```

2. **Synchronize the database** using a one-off command:

```bash
python -c "from server import create_app; app = create_app(); \
    from app.core.db import db; \
    with app.app_context(): db.create_all()"

```

3. **Update production** by modifying [`zerd.sql`](https://github.com/allen7d/mini-shop-server/blob/main/zerd.sql) and applying the SQL directly to the MySQL server.

## Summary

- The mini-shop-server manages database schema changes **manually** without Flask-Migrate or Alembic.
- Schema evolution relies on **model-first definitions** in `app/models/` followed by `db.create_all()` calls to create missing tables and columns.
- **Production deployments** use raw SQL dumps ([`zerd.sql`](https://github.com/allen7d/mini-shop-server/blob/main/zerd.sql)) rather than programmatic migrations, requiring manual synchronization between code and database state.

## Frequently Asked Questions

### Does mini-shop-server support automatic database migrations?

No, the repository does not include Flask-Migrate or Alembic in its dependencies. All schema changes must be performed manually by updating model classes and running `db.create_all()`, or by applying raw SQL scripts in production environments.

### What happens if I rename a column in a model?

Renaming a column requires manual intervention. The `db.create_all()` method only creates missing tables and columns; it does not alter existing columns or migrate data. You must either write a raw SQL `ALTER TABLE` statement to rename the column while preserving data, or use `db.drop_all()` followed by `db.create_all()` (which destroys all data).

### Where are the database models defined in the codebase?

All database models are located in the `app/models/` directory. Each Python file in this directory defines one or more tables as classes inheriting from `EntityModel` (defined in [`app/models/base.py`](https://github.com/allen7d/mini-shop-server/blob/main/app/models/base.py)), which provides the SQLAlchemy `db.Model` base class and common functionality.

### Is there a risk of data loss when using db.create_all()?

The `db.create_all()` method itself is non-destructive—it only creates tables and columns that do not already exist. However, if you call `db.drop_all()` to remove existing schema before `db.create_all()`, all data will be permanently deleted. Production environments should use the provided [`zerd.sql`](https://github.com/allen7d/mini-shop-server/blob/main/zerd.sql) dump or manual SQL `ALTER` statements to avoid data loss.