Overview
The project uses SQLite as its database, with migrations stored inapp/config/phinx/migrations/. Phinx manages schema changes and tracks which migrations have been applied.
Configuration
Phinx is configured inapp/config/phinx/phinx.php:
DB_PATH environment variable, which defaults to /var/www/data/cfbmarblegame.db in the Docker container.
Running Migrations
To apply all pending migrations, use themigrate Make target:
- Check which migrations have already been applied
- Run any new migrations in chronological order
- Update the
phinxlogtable to track the migration status
Rolling Back Migrations
To rollback the last migration, use:Creating a New Migration
To create a new migration, use themigration Make target with a descriptive name:
app/config/phinx/migrations/ with a timestamp prefix:
Migration Naming Conventions
Use descriptive names in PascalCase that clearly indicate what the migration does:CreateTeamsTable- Creates a new tableAddEmailToUsersTable- Adds a column to an existing tableRemoveSeasonTypeColumn- Removes a columnReplaceGamesTableToChangeColumnTypesAndAddChecks- Major structural changes
Writing Migrations
A migration file contains two methods:up()- Applied when running migrationsdown()- Applied when rolling back migrations
Example: Creating a Table
Here’s a real migration from the project that creates theteams table:
app/config/phinx/migrations/20250903111715_create_teams_table.php
Key Points
- Type Declarations: Use
declare(strict_types=1);for type safety - Class Names: Match the migration name in PascalCase
- Execute Method: Use
$this->execute()for raw SQL (common for SQLite) - Heredoc Syntax: Use heredoc (
<<<'SQL') for multi-line SQL statements - Reversibility: Ensure
down()properly reversesup()
Example: Modifying a Table
When making complex changes, you may need to recreate tables (SQLite limitation):Migration Workflow
Write Migration Logic
Edit the generated file in
app/config/phinx/migrations/ and implement:- The
up()method with your schema changes - The
down()method to reverse those changes
Best Practices
Always Include Down Methods
Even if you don’t plan to rollback, include adown() method for completeness and emergency situations.
One Logical Change Per Migration
Keep migrations focused on a single logical change (one table, one feature) for easier debugging and rollback.Test Before Committing
Always test bothup() and down() methods in your local environment before committing.
Use Transactions Carefully
Phinx automatically wraps migrations in transactions. Be aware of SQLite’s transaction limitations with DDL statements.Never Modify Existing Migrations
Once a migration has been applied in any environment (especially production), never modify it. Create a new migration instead.Checking Migration Status
To see which migrations have been applied:- Migration timestamps
- Migration names
- Whether they’ve been applied
- When they were applied
Troubleshooting
Migration fails to apply
- Check the error message for SQL syntax issues
- Verify the database connection is working
- Ensure the database file has write permissions
Cannot rollback migration
- Check that the
down()method is properly implemented - Verify there are no foreign key constraints preventing the rollback
- Review the migration order if rolling back multiple migrations
Migration applied but not showing in status
- Check the
phinxlogtable directly - Verify the Phinx configuration points to the correct database
- Ensure you’re checking the right environment