Files
orion/docs/getting-started/database-setup-guide.md
Samir Boulahtit e9253fbd84 refactor: rename Wizamart to Orion across entire codebase
Replace all ~1,086 occurrences of Wizamart/wizamart/WIZAMART/WizaMart
with Orion/orion/ORION across 184 files. This includes database
identifiers, email addresses, domain references, R2 bucket names,
DNS prefixes, encryption salt, Celery app name, config defaults,
Docker configs, CI configs, documentation, seed data, and templates.

Renames homepage-wizamart.html template to homepage-orion.html.
Fixes duplicate file_pattern key in api.yaml architecture rule.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 16:46:56 +01:00

884 lines
20 KiB
Markdown

# Database Setup & Initialization Guide
## Overview
This guide walks you through setting up the Orion database from scratch. Whether you're a new developer joining the team or need to reset your local database, this document covers everything you need to know.
---
## Table of Contents
1. [Prerequisites](#prerequisites)
2. [First-Time Setup](#first-time-setup)
3. [Database Reset (Clean Slate)](#database-reset-clean-slate)
4. [Verifying Your Setup](#verifying-your-setup)
5. [Common Issues & Solutions](#common-issues-solutions)
6. [Database Migrations](#database-migrations)
7. [Seeding Data](#seeding-data)
---
## Prerequisites
### Required Software
- **Python 3.11+**
- **Alembic** (installed via `requirements.txt`)
- **SQLite** (built into Python) or **PostgreSQL** (for production-like setup)
### Environment Setup
```bash
# 1. Clone the repository
git clone <orion-repo>
cd orion-repo
# 2. Create virtual environment
python -m venv venv
# 3. Activate virtual environment
# Windows:
venv\Scripts\activate
# Linux/Mac:
source venv/bin/activate
# 4. Install dependencies
pip install -r requirements.txt
```
---
## First-Time Setup
### Step 1: Configure Database Connection
Create or update `.env` file in project root:
```env
# Database Configuration
DATABASE_URL=sqlite:///./orion.db
# For PostgreSQL (production):
# DATABASE_URL=postgresql://user:password@localhost:5432/orion
# Other required settings
SECRET_KEY=your-secret-key-here-change-in-production
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
```
---
### Step 2: Initialize Alembic (First Time Only)
**If `alembic/` folder doesn't exist:**
```bash
# Initialize Alembic
alembic init alembic
```
**Configure `alembic.ini`:**
```ini
# alembic.ini
# Find this line and update:
sqlalchemy.url = sqlite:///./orion.db
# Or for PostgreSQL:
# sqlalchemy.url = postgresql://user:password@localhost:5432/orion
```
**Configure `alembic/env.py`:**
```python
# alembic/env.py
# Add this near the top (after imports)
import sys
from pathlib import Path
# Add project root to Python path
sys.path.append(str(Path(__file__).parents[1]))
# ============================================================================
# CRITICAL: Import ALL database models here
# ============================================================================
from models.database.user import User
from models.database.store import Store
from models.database.store_domain import StoreDomain
from models.database.store_theme import StoreTheme
from models.database.customer import Customer
from models.database.team import Team, TeamMember, TeamInvitation
from models.database.product import Product
from models.database.marketplace_product import MarketplaceProduct
from models.database.inventory import Inventory
from models.database.order import Order
from models.database.marketplace_import_job import MarketplaceImportJob
# Import Base
from app.core.database import Base
# Set target metadata
target_metadata = Base.metadata
```
---
### Step 3: Generate Initial Migration
```bash
# Generate migration from your models
alembic revision --autogenerate -m "Initial migration - all tables"
# You should see output listing all detected tables:
# INFO [alembic.autogenerate.compare] Detected added table 'users'
# INFO [alembic.autogenerate.compare] Detected added table 'stores'
# INFO [alembic.autogenerate.compare] Detected added table 'store_themes'
# etc.
```
---
### Step 4: Apply Migration
```bash
# Apply the migration to create all tables
alembic upgrade head
# You should see:
# INFO [alembic.runtime.migration] Running upgrade -> abc123def456, Initial migration - all tables
```
---
### Step 5: Seed Initial Data
Create an admin user and test store:
```bash
python scripts/seed_database.py
```
**Or manually:**
```python
# Run Python interactive shell
python
# Then execute:
from app.core.database import SessionLocal
from models.database.user import User
from models.database.store import Store
from middleware.auth import AuthManager
from datetime import datetime, timezone
db = SessionLocal()
auth_manager = AuthManager()
# Create admin user
admin = User(
username="admin",
email="admin@orion.lu",
hashed_password=auth_manager.hash_password("admin123"),
role="admin",
is_active=True,
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc)
)
db.add(admin)
db.flush()
# Create test store
store = Store(
store_code="TESTSTORE",
subdomain="teststore",
name="Test Store",
description="Development test store",
owner_user_id=admin.id,
contact_email="contact@teststore.com",
is_active=True,
is_verified=True,
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc)
)
db.add(store)
db.commit()
print("✅ Admin user and test store created!")
db.close()
exit()
```
---
### Step 6: Start the Application
```bash
# Start FastAPI server
python -m uvicorn app.main:app --reload
# Server should start on http://localhost:8000
```
**Test the setup:**
- Admin login: http://localhost:8000/admin/login
- Username: `admin`
- Password: `admin123`
---
## Database Reset (Clean Slate)
Use this when you want to completely reset your database and start fresh.
⚠️ **WARNING:** This will delete ALL data! Make a backup if needed.
---
### Quick Reset Script (Windows PowerShell)
**Create `scripts/reset_database.ps1`:**
```powershell
# scripts/reset_database.ps1
Write-Host "🗑️ Database Reset Script" -ForegroundColor Cyan
Write-Host "This will delete ALL data!" -ForegroundColor Red
$confirm = Read-Host "Type 'YES' to continue"
if ($confirm -ne "YES") {
Write-Host "Aborted." -ForegroundColor Yellow
exit
}
Write-Host ""
Write-Host "Step 1: Backing up current database..." -ForegroundColor Yellow
if (Test-Path orion.db) {
$backupName = "orion_backup_$(Get-Date -Format 'yyyyMMdd_HHmmss').db"
Copy-Item orion.db $backupName
Write-Host "✓ Backup created: $backupName" -ForegroundColor Green
}
Write-Host ""
Write-Host "Step 2: Removing old migrations..." -ForegroundColor Yellow
Remove-Item alembic\versions\*.py -Exclude __init__.py -ErrorAction SilentlyContinue
Remove-Item -Recurse -Force alembic\versions\__pycache__ -ErrorAction SilentlyContinue
# Ensure __init__.py exists
if (-not (Test-Path alembic\versions\__init__.py)) {
New-Item -Path alembic\versions\__init__.py -ItemType File | Out-Null
}
Write-Host "✓ Old migrations removed" -ForegroundColor Green
Write-Host ""
Write-Host "Step 3: Deleting database..." -ForegroundColor Yellow
Remove-Item orion.db -ErrorAction SilentlyContinue
Write-Host "✓ Database deleted" -ForegroundColor Green
Write-Host ""
Write-Host "Step 4: Generating new migration..." -ForegroundColor Yellow
alembic revision --autogenerate -m "Initial migration - all tables"
Write-Host "✓ Migration generated" -ForegroundColor Green
Write-Host ""
Write-Host "Step 5: Applying migration..." -ForegroundColor Yellow
alembic upgrade head
Write-Host "✓ Migration applied" -ForegroundColor Green
Write-Host ""
Write-Host "Step 6: Verifying tables..." -ForegroundColor Yellow
python -c @"
import sqlite3
conn = sqlite3.connect('orion.db')
cursor = conn.cursor()
cursor.execute('SELECT name FROM sqlite_master WHERE type=\"table\" ORDER BY name;')
tables = [t[0] for t in cursor.fetchall()]
print('\n📊 Tables created:')
for t in tables:
print(f' {t}')
print(f'\n Total: {len(tables)} tables')
if 'store_themes' in tables:
print(' store_themes table confirmed!')
conn.close()
"@
Write-Host ""
Write-Host "Step 7: Seeding initial data..." -ForegroundColor Yellow
python scripts/seed_database.py
Write-Host ""
Write-Host "✅ Database reset complete!" -ForegroundColor Green
Write-Host ""
Write-Host "Next steps:" -ForegroundColor Cyan
Write-Host " 1. Start server: python -m uvicorn app.main:app --reload" -ForegroundColor White
Write-Host " 2. Login: http://localhost:8000/admin/login" -ForegroundColor White
Write-Host " 3. Username: admin | Password: admin123" -ForegroundColor White
```
**Run it:**
```powershell
# First time only - allow script execution
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
# Run the reset
.\scripts\reset_database.ps1
```
---
### Quick Reset Script (Linux/Mac Bash)
**Create `scripts/reset_database.sh`:**
```bash
#!/bin/bash
# scripts/reset_database.sh
echo "🗑️ Database Reset Script"
echo "⚠️ This will delete ALL data!"
read -p "Type 'YES' to continue: " confirm
if [ "$confirm" != "YES" ]; then
echo "Aborted."
exit 1
fi
echo ""
echo "Step 1: Backing up current database..."
if [ -f orion.db ]; then
backup_name="orion_backup_$(date +%Y%m%d_%H%M%S).db"
cp orion.db "$backup_name"
echo "✓ Backup created: $backup_name"
fi
echo ""
echo "Step 2: Removing old migrations..."
find alembic/versions -type f -name "*.py" ! -name "__init__.py" -delete
rm -rf alembic/versions/__pycache__
touch alembic/versions/__init__.py
echo "✓ Old migrations removed"
echo ""
echo "Step 3: Deleting database..."
rm -f orion.db
echo "✓ Database deleted"
echo ""
echo "Step 4: Generating new migration..."
alembic revision --autogenerate -m "Initial migration - all tables"
echo "✓ Migration generated"
echo ""
echo "Step 5: Applying migration..."
alembic upgrade head
echo "✓ Migration applied"
echo ""
echo "Step 6: Verifying tables..."
python -c "
import sqlite3
conn = sqlite3.connect('orion.db')
cursor = conn.cursor()
cursor.execute('SELECT name FROM sqlite_master WHERE type=\"table\" ORDER BY name;')
tables = [t[0] for t in cursor.fetchall()]
print('\n📊 Tables created:')
for t in tables:
print(f' ✓ {t}')
print(f'\n✅ Total: {len(tables)} tables')
if 'store_themes' in tables:
print('✅ store_themes table confirmed!')
conn.close()
"
echo ""
echo "Step 7: Seeding initial data..."
python scripts/seed_database.py
echo ""
echo "✅ Database reset complete!"
echo ""
echo "Next steps:"
echo " 1. Start server: python -m uvicorn app.main:app --reload"
echo " 2. Login: http://localhost:8000/admin/login"
echo " 3. Username: admin | Password: admin123"
```
**Run it:**
```bash
chmod +x scripts/reset_database.sh
./scripts/reset_database.sh
```
---
### Manual Reset Steps
If you prefer to run commands manually:
```bash
# 1. Backup (optional)
cp orion.db orion_backup.db # Windows: copy orion.db orion_backup.db
# 2. Remove migrations
rm alembic/versions/*.py # Windows: Remove-Item alembic\versions\*.py -Exclude __init__.py
touch alembic/versions/__init__.py # Windows: New-Item -Path alembic\versions\__init__.py
# 3. Delete database
rm orion.db # Windows: Remove-Item orion.db
# 4. Generate migration
alembic revision --autogenerate -m "Initial migration - all tables"
# 5. Apply migration
alembic upgrade head
# 6. Seed data
python scripts/seed_database.py
```
---
## Verifying Your Setup
### Check Alembic Status
```bash
# Check current migration version
alembic current
# Should show:
# <revision_id> (head)
```
### Verify Tables Exist
**Using Python:**
```python
import sqlite3
conn = sqlite3.connect('orion.db')
cursor = conn.cursor()
# List all tables
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;")
tables = cursor.fetchall()
print("📊 Database Tables:")
for table in tables:
print(f"{table[0]}")
# Check specific table structure
cursor.execute("PRAGMA table_info(store_themes);")
columns = cursor.fetchall()
print("\n📋 store_themes columns:")
for col in columns:
print(f" - {col[1]} ({col[2]})")
conn.close()
```
### Test Database Connection
```bash
# Start Python shell
python
# Test connection
from app.core.database import SessionLocal, engine
from sqlalchemy import text
db = SessionLocal()
result = db.execute(text("SELECT name FROM sqlite_master WHERE type='table';"))
tables = [row[0] for row in result]
print("✅ Database connection successful!")
print(f"📊 Tables found: {len(tables)}")
for table in tables:
print(f" - {table}")
db.close()
exit()
```
### Test Application Startup
```bash
# Start server
python -m uvicorn app.main:app --reload
# Should see:
# INFO: Uvicorn running on http://127.0.0.1:8000
# INFO: Application startup complete.
```
**No errors = successful setup!**
---
## Common Issues & Solutions
### Issue 1: "No such table" Error
**Symptom:**
```
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: store_themes
```
**Solution:**
```bash
# 1. Check if model is imported in alembic/env.py
# Open alembic/env.py and verify:
from models.database.store_theme import StoreTheme
# 2. Regenerate migration
alembic revision --autogenerate -m "Add missing tables"
# 3. Apply migration
alembic upgrade head
```
---
### Issue 2: "Target database is not up to date"
**Symptom:**
```
ERROR [alembic.util.messaging] Target database is not up to date.
```
**Solution:**
```bash
# Option 1: Stamp to current head
alembic stamp head
# Option 2: Check and upgrade
alembic current # See current version
alembic upgrade head # Upgrade to latest
# Option 3: Full reset (see Database Reset section)
```
---
### Issue 3: Database Locked
**Symptom:**
```
sqlite3.OperationalError: database is locked
```
**Solution:**
```bash
# 1. Stop the FastAPI server (Ctrl+C)
# 2. Kill any Python processes
# Windows:
taskkill /F /IM python.exe
# Linux/Mac:
pkill python
# 3. Close any database browser applications
# 4. Try again
alembic upgrade head
```
---
### Issue 4: Migration File Conflicts
**Symptom:**
```
Multiple head revisions are present
```
**Solution:**
```bash
# Option 1: Merge migrations
alembic merge heads -m "Merge migrations"
alembic upgrade head
# Option 2: Clean reset (recommended for development)
# See Database Reset section above
```
---
### Issue 5: Import Errors in alembic/env.py
**Symptom:**
```
ModuleNotFoundError: No module named 'models'
```
**Solution:**
Check `alembic/env.py` has correct path setup:
```python
# alembic/env.py (top of file)
import sys
from pathlib import Path
# Add project root to Python path
sys.path.append(str(Path(__file__).parents[1]))
```
---
## Database Migrations
### Creating New Migrations
When you add/modify models:
```bash
# 1. Update your model file (e.g., models/database/store_theme.py)
# 2. Generate migration
alembic revision --autogenerate -m "Add new field to store_themes"
# 3. Review the generated migration
# Check: alembic/versions/<revision>_add_new_field_to_store_themes.py
# 4. Apply migration
alembic upgrade head
```
---
### Migration Best Practices
**DO:**
- Review generated migrations before applying
- Use descriptive migration messages
- Test migrations on development database first
- Keep migrations small and focused
- Commit migrations to version control
**DON'T:**
- Edit applied migrations (create new ones instead)
- Delete migration files from version control
- Skip migration review
- Combine unrelated changes in one migration
---
### Rolling Back Migrations
```bash
# Downgrade one version
alembic downgrade -1
# Downgrade to specific revision
alembic downgrade <revision_id>
# Downgrade to base (empty database)
alembic downgrade base
```
---
## Seeding Data
### Development Data Seed
**Create `scripts/seed_database.py`:**
```python
# scripts/seed_database.py
"""
Seed the database with initial development data.
"""
from app.core.database import SessionLocal
from models.database.user import User
from models.database.store import Store
from app.core.security import get_password_hash
from datetime import datetime, timezone
def seed_database():
"""Seed database with initial data."""
db = SessionLocal()
try:
print("🌱 Seeding database...")
# Check if admin already exists
existing_admin = db.query(User).filter(User.username == "admin").first()
if existing_admin:
print("⚠️ Admin user already exists, skipping...")
return
# Create admin user
admin = User(
username="admin",
email="admin@orion.lu",
hashed_password=get_password_hash("admin123"),
is_admin=True,
is_active=True,
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc)
)
db.add(admin)
db.flush()
print(f"✓ Admin user created (ID: {admin.id})")
# Create test store
store = Store(
store_code="TESTSTORE",
subdomain="teststore",
name="Test Store",
description="Development test store",
owner_user_id=admin.id,
contact_email="contact@teststore.com",
is_active=True,
is_verified=True,
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc)
)
db.add(store)
db.flush()
print(f"✓ Test store created: {store.store_code}")
db.commit()
print("\n✅ Database seeded successfully!")
print("\n📝 Login Credentials:")
print(" URL: http://localhost:8000/admin/login")
print(" Username: admin")
print(" Password: admin123")
except Exception as e:
db.rollback()
print(f"❌ Error seeding database: {e}")
raise
finally:
db.close()
if __name__ == "__main__":
seed_database()
```
**Run it:**
```bash
python scripts/seed_database.py
```
---
### Production Data Migration
For production, create separate seed scripts:
```python
# scripts/seed_production.py
# - Create only essential admin user
# - No test data
# - Strong passwords from environment variables
```
---
## Quick Reference
### Essential Commands
```bash
# Check migration status
alembic current
# Generate new migration
alembic revision --autogenerate -m "Description"
# Apply migrations
alembic upgrade head
# Rollback one migration
alembic downgrade -1
# View migration history
alembic history
# Seed database
python scripts/seed_database.py
# Start server
python -m uvicorn app.main:app --reload
```
---
### File Locations
```
project/
├── alembic/
│ ├── versions/ # Migration files here
│ │ └── __init__.py
│ ├── env.py # Alembic configuration (import models here!)
│ └── script.py.mako
├── app/
│ └── core/
│ └── database.py # Database connection
├── models/
│ └── database/ # SQLAlchemy models
│ ├── user.py
│ ├── store.py
│ ├── store_theme.py
│ └── ...
├── scripts/
│ ├── seed_database.py # Development seed
│ └── reset_database.ps1 # Reset script
├── alembic.ini # Alembic config
├── orion.db # SQLite database (gitignored)
└── .env # Environment variables (gitignored)
```
---
## Getting Help
### Internal Resources
- **Architecture Guide:** `docs/PROPER_ARCHITECTURE_GUIDE.md`
- **Exception Handling:** `docs/EXCEPTION_PATTERN_EXPLAINED.md`
- **Admin Feature Guide:** `docs/ADMIN_FEATURE_INTEGRATION_GUIDE.md`
### External Resources
- [Alembic Documentation](https://alembic.sqlalchemy.org/)
- [SQLAlchemy Documentation](https://docs.sqlalchemy.org/)
- [FastAPI Documentation](https://fastapi.tiangolo.com/)
---
## Contributing
When adding new models:
1. ✅ Create the model in `models/database/`
2. ✅ Import it in `alembic/env.py`
3. ✅ Generate migration: `alembic revision --autogenerate -m "Add XYZ model"`
4. ✅ Review the migration file
5. ✅ Test locally: `alembic upgrade head`
6. ✅ Commit both model and migration files
---
**Last Updated:** 2025-10-27
**Maintainer:** Development Team
**Questions?** Contact the team lead or check internal documentation.