346 lines
8.0 KiB
Markdown
346 lines
8.0 KiB
Markdown
# BREEDR Database Migrations
|
|
|
|
## Automatic Migration System
|
|
|
|
BREEDR now includes an **automatic migration system** that runs on every startup to ensure your database schema is always correct and up-to-date.
|
|
|
|
## How It Works
|
|
|
|
### On Every Startup
|
|
|
|
1. **Initialize Database** - Creates tables if they don't exist
|
|
2. **Run Migrations** - Automatically fixes schema issues
|
|
3. **Validate Schema** - Verifies everything is correct
|
|
4. **Start Application** - Server begins accepting requests
|
|
|
|
You don't need to do anything manually!
|
|
|
|
---
|
|
|
|
## Migrations Included
|
|
|
|
### Migration 001: Remove Old Parent Columns
|
|
|
|
**Problem**: Old schema had `sire` and `dam` columns in the `dogs` table causing "no such column: sire" errors.
|
|
|
|
**Solution**:
|
|
- Creates `parents` table for relationships
|
|
- Migrates existing sire/dam data to `parents` table
|
|
- Recreates `dogs` table without sire/dam columns
|
|
- Preserves all existing dog data
|
|
|
|
**Automatic**: Runs only if old schema detected
|
|
|
|
### Migration 002: Add Litter ID Column
|
|
|
|
**Problem**: Dogs table missing `litter_id` column for linking puppies to litters.
|
|
|
|
**Solution**:
|
|
- Adds `litter_id` column to `dogs` table
|
|
- Creates foreign key to `litters` table
|
|
|
|
**Automatic**: Runs only if column is missing
|
|
|
|
---
|
|
|
|
## Schema Version Tracking
|
|
|
|
The migration system uses a `schema_version` table to track which migrations have been applied:
|
|
|
|
```sql
|
|
CREATE TABLE schema_version (
|
|
version INTEGER PRIMARY KEY,
|
|
applied_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
description TEXT
|
|
);
|
|
```
|
|
|
|
Each migration runs only once, even if you restart the server multiple times.
|
|
|
|
---
|
|
|
|
## Correct Schema (Current)
|
|
|
|
### Dogs Table (No sire/dam columns!)
|
|
|
|
```sql
|
|
CREATE TABLE dogs (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
registration_number TEXT,
|
|
microchip TEXT,
|
|
sex TEXT CHECK(sex IN ('male', 'female')),
|
|
birth_date DATE,
|
|
breed TEXT,
|
|
color TEXT,
|
|
weight REAL,
|
|
height REAL,
|
|
notes TEXT,
|
|
litter_id INTEGER,
|
|
photo_urls TEXT,
|
|
is_active INTEGER DEFAULT 1,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (litter_id) REFERENCES litters(id) ON DELETE SET NULL
|
|
);
|
|
```
|
|
|
|
### Parents Table (Relationships)
|
|
|
|
```sql
|
|
CREATE TABLE parents (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
dog_id INTEGER NOT NULL,
|
|
parent_id INTEGER NOT NULL,
|
|
parent_type TEXT NOT NULL CHECK(parent_type IN ('sire', 'dam')),
|
|
FOREIGN KEY (dog_id) REFERENCES dogs(id) ON DELETE CASCADE,
|
|
FOREIGN KEY (parent_id) REFERENCES dogs(id) ON DELETE CASCADE,
|
|
UNIQUE(dog_id, parent_type)
|
|
);
|
|
```
|
|
|
|
---
|
|
|
|
## How to Use
|
|
|
|
### Normal Startup (Automatic)
|
|
|
|
Just start your application normally:
|
|
|
|
```bash
|
|
# With Docker
|
|
docker-compose up -d
|
|
|
|
# Without Docker
|
|
cd server && npm start
|
|
```
|
|
|
|
Migrations run automatically!
|
|
|
|
### Check Migration Logs
|
|
|
|
Look at the server console output:
|
|
|
|
```
|
|
============================================================
|
|
BREEDR Database Migration System
|
|
============================================================
|
|
Database: /app/data/breedr.db
|
|
|
|
Current schema version: 0
|
|
|
|
[Migration 001] Checking for old sire/dam columns...
|
|
[Migration 001] Found old schema with sire/dam columns
|
|
[Migration 001] Migrating to parents table...
|
|
[Migration 001] Backed up 15 dogs
|
|
[Migration 001] Migrated 8 sire relationships
|
|
[Migration 001] Migrated 8 dam relationships
|
|
[Migration 001] Dropped old dogs table
|
|
[Migration 001] Created new dogs table
|
|
[Migration 001] Restored 15 dogs
|
|
[Migration 001] ✓ Migration complete!
|
|
|
|
[Migration 002] Checking for litter_id column...
|
|
[Migration 002] litter_id column already exists, skipping
|
|
|
|
[Validation] ✓ Dogs table exists
|
|
[Validation] ✓ Dogs table has no sire/dam columns
|
|
[Validation] ✓ Parents table exists
|
|
[Validation] ✓ Litter_id column exists
|
|
[Validation] ✓ Litters table exists
|
|
[Validation] ✓ All schema checks passed!
|
|
|
|
============================================================
|
|
Schema version: 0 → 2
|
|
Migration system complete!
|
|
============================================================
|
|
```
|
|
|
|
### Manual Migration (If Needed)
|
|
|
|
You can also run migrations manually:
|
|
|
|
```bash
|
|
node server/db/migrations.js
|
|
```
|
|
|
|
---
|
|
|
|
## Fresh Install
|
|
|
|
For a fresh installation:
|
|
|
|
1. **No database file exists** → `init.js` creates correct schema
|
|
2. **Migrations check schema** → Everything already correct, no migration needed
|
|
3. **Application starts** → Ready to use!
|
|
|
|
**Result**: Fresh installs automatically have the correct schema.
|
|
|
|
---
|
|
|
|
## Upgrading from Old Version
|
|
|
|
For existing installations with old schema:
|
|
|
|
1. **Old database detected** → Migration system kicks in
|
|
2. **Data is backed up** → Safety first!
|
|
3. **Schema is updated** → Sire/dam data moved to parents table
|
|
4. **Data is restored** → All your dogs are preserved
|
|
5. **Application starts** → Now using correct schema!
|
|
|
|
**Result**: Existing data is preserved and schema is fixed automatically.
|
|
|
|
---
|
|
|
|
## Docker Integration
|
|
|
|
### Dockerfile
|
|
|
|
No changes needed! Migrations run automatically when the container starts.
|
|
|
|
### docker-compose.yml
|
|
|
|
No changes needed! Just restart:
|
|
|
|
```bash
|
|
docker-compose restart
|
|
```
|
|
|
|
Or rebuild:
|
|
|
|
```bash
|
|
docker-compose down
|
|
docker-compose up --build -d
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Migration Failed
|
|
|
|
If you see an error:
|
|
|
|
```
|
|
⚠️ Database migration failed!
|
|
Error: [error message]
|
|
```
|
|
|
|
1. **Check the error message** - It will tell you what went wrong
|
|
2. **Check database file permissions** - Make sure the file is writable
|
|
3. **Check disk space** - Ensure you have enough space
|
|
4. **Try manual migration**:
|
|
```bash
|
|
node server/db/migrations.js
|
|
```
|
|
|
|
### Database is Locked
|
|
|
|
If migrations fail with "database is locked":
|
|
|
|
1. Stop all running instances of BREEDR
|
|
2. Check for zombie processes: `ps aux | grep node`
|
|
3. Kill any old processes: `kill <PID>`
|
|
4. Restart BREEDR
|
|
|
|
### Migration Keeps Running
|
|
|
|
If the same migration runs every time:
|
|
|
|
1. Check `schema_version` table:
|
|
```sql
|
|
SELECT * FROM schema_version;
|
|
```
|
|
2. If empty, migration isn't being recorded
|
|
3. Check for database transaction issues
|
|
4. Manually add version:
|
|
```sql
|
|
INSERT INTO schema_version (version, description) VALUES (1, 'Manual fix');
|
|
```
|
|
|
|
### Want to Start Fresh
|
|
|
|
To completely reset the database:
|
|
|
|
1. **Stop BREEDR**
|
|
2. **Backup your data** (optional):
|
|
```bash
|
|
cp data/breedr.db data/breedr.db.backup
|
|
```
|
|
3. **Delete database**:
|
|
```bash
|
|
rm data/breedr.db
|
|
```
|
|
4. **Restart BREEDR** - Fresh database will be created
|
|
|
|
---
|
|
|
|
## Validation Checks
|
|
|
|
The migration system validates your schema:
|
|
|
|
- ✓ Dogs table exists
|
|
- ✓ Dogs table has no sire/dam columns
|
|
- ✓ Parents table exists
|
|
- ✓ Litter_id column exists
|
|
- ✓ Litters table exists
|
|
|
|
If any check fails, you'll see a warning.
|
|
|
|
---
|
|
|
|
## Adding New Migrations
|
|
|
|
If you need to add a new migration:
|
|
|
|
1. **Edit `server/db/migrations.js`**
|
|
2. **Add new migration function**:
|
|
```javascript
|
|
migration003_yourNewMigration() {
|
|
console.log('[Migration 003] Doing something...');
|
|
// Your migration code here
|
|
}
|
|
```
|
|
3. **Add to runMigrations()**:
|
|
```javascript
|
|
if (currentVersion < 3) {
|
|
this.migration003_yourNewMigration();
|
|
this.recordMigration(3, 'Description of migration');
|
|
}
|
|
```
|
|
4. **Test thoroughly** before deploying
|
|
|
|
---
|
|
|
|
## Best Practices
|
|
|
|
1. **Let migrations run automatically** - Don't skip them
|
|
2. **Check logs on startup** - Verify migrations succeeded
|
|
3. **Backup before major updates** - Safety first
|
|
4. **Test in development** - Before deploying to production
|
|
5. **Monitor schema_version** - Know what version you're on
|
|
|
|
---
|
|
|
|
## Schema Version History
|
|
|
|
| Version | Description | Date |
|
|
|---------|-------------|------|
|
|
| 0 | Initial schema (may have sire/dam columns) | - |
|
|
| 1 | Migrated to parents table | March 2026 |
|
|
| 2 | Added litter_id column | March 2026 |
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
✅ **Migrations run automatically on every startup**
|
|
✅ **No manual intervention needed**
|
|
✅ **Data is preserved during migrations**
|
|
✅ **Schema is validated after migrations**
|
|
✅ **Works with Docker and standalone**
|
|
✅ **Fresh installs get correct schema**
|
|
✅ **Old installs are automatically upgraded**
|
|
|
|
**The "no such column: sire" error is now fixed automatically!** 🎉
|