Files
breedr/DATABASE_MIGRATIONS.md

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

  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:

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:

  1. No database file existsinit.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:

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]
  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:
    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:
    SELECT * FROM schema_version;
    
  2. If empty, migration isn't being recorded
  3. Check for database transaction issues
  4. Manually add version:
    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):
    cp data/breedr.db data/breedr.db.backup
    
  3. Delete database:
    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:
    migration003_yourNewMigration() {
      console.log('[Migration 003] Doing something...');
      // Your migration code here
    }
    
  3. Add to runMigrations():
    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! 🎉