Keeping your schema.rb file clean and consistent between environments | Snapsheet

Keeping your schema.rb file clean and consistent between environments

What issues does an inconsistent schema.rb file cause?

Having an inconsistent schema.rb file that doesn’t really reflect the structure in production can create an array of problems:

How are these inconsistencies introduced?

Most inconsistencies are introduced by running migrations in a different order on different databases. Here’s an example:

1. Developer Lionel creates a migration that adds the column nickname to the students table locally.

2. Later, Santiago creates a migration that adds the column nationality to the same students table in his local environment.

3. Santiago merges his code to main, which updates production with his migrations.

4. Developer Lionel pulls the latest main and merges it onto his branch, encountering conflicts in schema.rb.

5. After resolving the conflict and running the migrations, Lionel has a different versioning in schema.rb compared to production.

6. Future runs of migrations lead to inconsistencies in table column ordering.

How to manually fix an inconsistent schema.rb that has deviated from the production database schema

To fix schema.rb to reflect the state of production, follow these steps:

1. Create a new, temporary database:

CREATE DATABASE schema_fix_development;

2. Get “create table” statements from production:

mysqldump -h <prod-host> -u <prod-username> --password=******** --no-data --compact <database-name> > ~/tmp/db/prod-create-tables.sql

3. Run “create table” commands on the new database:

mysql -u root schema_fix_development < ~/tmp/db/prod-create-tables.sql

4. Get all migration versions from the main branch:

for migration_file in `ls ./db/migrate | sort`; do echo $migration_file | grep '^[0-9]\+' -o; done > ~/tmp/migration_versions.txt

5. Populate the schema migrations table with all migrations:

for migration_version in `cat ~/tmp/migration_versions.txt`; do echo "INSERT INTO schema_migrations VALUES ('$migration_version');"; done > ~/tmp/migration_versions.sql

6. Point your local server to this new schema_fix_development database by updating your database.yml file or the DATABASE_URL environment variable. 7. Run rake db:migrate to update schema.rb. 8. Commit and merge changes to schema.rb after verifying the production schema. 9. Rollback migrations on your local database if needed and repeat steps until no differences exist.

How do we prevent these issues moving forward?

Ensure that migrations run in the same order on all databases. Follow these guidelines:

Before merging any migration to the main branch, confirm: