8.0 KiB
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
- Initialize Database - Creates tables if they don't exist
- Run Migrations - Automatically fixes schema issues
- Validate Schema - Verifies everything is correct
- 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
parentstable for relationships - Migrates existing sire/dam data to
parentstable - Recreates
dogstable 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_idcolumn todogstable - Creates foreign key to
litterstable
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:
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!)
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)
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:
# 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:
node server/db/migrations.js
Fresh Install
For a fresh installation:
- No database file exists →
init.jscreates correct schema - Migrations check schema → Everything already correct, no migration needed
- Application starts → Ready to use!
Result: Fresh installs automatically have the correct schema.
Upgrading from Old Version
For existing installations with old schema:
- Old database detected → Migration system kicks in
- Data is backed up → Safety first!
- Schema is updated → Sire/dam data moved to parents table
- Data is restored → All your dogs are preserved
- 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:
docker-compose restart
Or rebuild:
docker-compose down
docker-compose up --build -d
Troubleshooting
Migration Failed
If you see an error:
⚠️ Database migration failed!
Error: [error message]
- Check the error message - It will tell you what went wrong
- Check database file permissions - Make sure the file is writable
- Check disk space - Ensure you have enough space
- Try manual migration:
node server/db/migrations.js
Database is Locked
If migrations fail with "database is locked":
- Stop all running instances of BREEDR
- Check for zombie processes:
ps aux | grep node - Kill any old processes:
kill <PID> - Restart BREEDR
Migration Keeps Running
If the same migration runs every time:
- Check
schema_versiontable:SELECT * FROM schema_version; - If empty, migration isn't being recorded
- Check for database transaction issues
- Manually add version:
INSERT INTO schema_version (version, description) VALUES (1, 'Manual fix');
Want to Start Fresh
To completely reset the database:
- Stop BREEDR
- Backup your data (optional):
cp data/breedr.db data/breedr.db.backup - Delete database:
rm data/breedr.db - 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:
- Edit
server/db/migrations.js - Add new migration function:
migration003_yourNewMigration() { console.log('[Migration 003] Doing something...'); // Your migration code here } - Add to runMigrations():
if (currentVersion < 3) { this.migration003_yourNewMigration(); this.recordMigration(3, 'Description of migration'); } - Test thoroughly before deploying
Best Practices
- Let migrations run automatically - Don't skip them
- Check logs on startup - Verify migrations succeeded
- Backup before major updates - Safety first
- Test in development - Before deploying to production
- 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! 🎉