16

Currently I'm working with a huge rails application and multiple branches with each a new feature for this application. It happens a lot a feature will require migrations, which shouldn't be a problem until you merge it with master: schema.rb got updated with the information of your dev database!

To clarify:

1. Branch A has migration create_table_x
2. Branch B has migration create_table_y
3. Branch A adds another create_table_z and runs db:migrate
4. You want to merge Branch A with Master and you see table_x, table_y and table_z in the schema.rb of Branch A.

It's not an option to reset+seed the database before every migration in a branch or create a database per branch. Due to the huge size of 2 GB SQL data, it would not be workable.

My question:

Is it really required to keep schema.rb in the repository since it gets rebuilt every migration?

If so, is it possible to build schema off the migrations instead of database dump?

Vikko
  • 1,396
  • 10
  • 23
  • I think you should keep your schema.rb in your repository. It could happen, that somebody cleans up the migration files and delete a few unused migration from the past..and if you do not have an uniform schema.rb I could end up in a mess. the schema file gets updated every migration, not completely rebuild. but anyway an interesting question. – Matthias May 08 '13 at 10:48
  • yes, the issue is it's being generated of the current database structure, regardless if the tables in the database were added in the parent or the branch you're in. Thats what I meant with 'rebuilt'. I hope someone knows a nicer way then dropping / copying the database from master each time you switch a branch with migrations :) – Vikko May 08 '13 at 11:19
  • Possible duplicate of [What is the preferred way to manage schema.rb in git?](http://stackoverflow.com/questions/737854/what-is-the-preferred-way-to-manage-schema-rb-in-git) – Tachyons Apr 07 '17 at 09:25

3 Answers3

11

you should keep the schema within your repo. running the migration will fix merge conflicts within your schema.rb file for you. my simple take on your questions

  1. Is it Required? not really, but good practice.

"It's strongly recommended to check this file into your version control system." -schema.rb

  1. It is possible? yes but you may want to ask yourself if you really save any time by doing so, either manually or building the schema off your migrations elsewhere and pushing it in.

you ge tthe added benefit of using

rake db:schema:load

and

rake db:schema:dump

http://tbaggery.com/2010/10/24/reduce-your-rails-schema-conflicts.html

Stephen Nguyen
  • 5,357
  • 5
  • 24
  • 28
2

Keeping schema.rb in the repo is important, because you want a new developer (or your test environment) to be able to generate a new database just from schema.rb. When you have a lot of migrations, they may not all continue to run, especially if they rely on model classes that don't exist, or have changed, or have different validations in effect than when the migration was first run. When you run your tests, you want to dump and recreate your database from schema.rb, not by re-running all the migrations every time you run the full test suite.

If you're working on two different feature branches simultaneously, and changing the database structure in both, I think schema.rb is the least of your problems. If you rename or remove a column in branch B, branch A is going to break whenever it references the old column. If all they're doing is creating new tables, it's not as bad, but then you want schema.rb to be updated when you merge from master into A, so that A doesn't try to run the migration a second time and fail because the new table already exists.

If that doesn't answer your question, maybe you could explain your workflow a little more?

sockmonk
  • 4,195
  • 24
  • 40
  • That is correct, but you don't want the tables of branch B (where you executed the migrations) show up in master BEFORE you merge branch B. For instance: If there is a table that is used in both branch A and branch B, **branch B changes name to last_name**, **branch A changes initials to first_name**. You merge branch A, you dont merge branch B because it has some complications => the **schema generated contains first_name and last_name**, while you would rather have **first_name and name**. Some logic might be nice to check for migrations not in master and rollback them in the schema.rb – Vikko May 15 '13 at 10:17
  • That sounds good at first, but some migrations might not be so reversible. You could probably accomplish this manually via: rake db:migrate VERSION=123 where 123 is the migration number in your schema.rb. That should migrate either forwards or backwards as needed to get to that version. Ultimately, your best bet is going to be to get at least the migrations from each branch merged into master at the earliest possible time, even if you have to do it by cherry-picking. – sockmonk May 15 '13 at 20:05
  • 1
    I'm aware of that, but the issue is working with about 20 branches which all have a lifetime between a few hours and a few months.. Thats where the complications come in: You forget the branch had migrations and you're screwed! Besides that, migrations on a big table (100.000+ records) take ages. You'd rather leave them there for development and update just the schema if the table is not used in your current branch. – Vikko May 16 '13 at 09:31
1

Fresh Temporary DB as a quick workaround

For example, do the following whenever you need pretty db/schema.rb on particular branch:

  1. git checkout -- db/schema.rb
  2. switch to the different development database, i.e. update config/database.yml
  3. rake db:drop && rake db:setup
  4. rake db:migrate
  5. commit your pretty db/schema.rb
  6. revert changes in config/database.yaml
wik
  • 2,462
  • 1
  • 24
  • 29