2

I'm helping out with a friend's rails app. They have a database that contains many tables which were added manually using SQL rather than with rails migrations. They've started adding migrations normally, but they need to get the two back in sync.

If we add the migrations now, they'll error because those tables/columns already exist. If we leave them out, people have to use db:schema:load to get up and running, and then run migrations one at a time by name to avoid errors. We'd like to avoid that and get back to a healthy state instead.

Does anyone know of a better way to get the migrations back in step with the database? We have to do this without losing any data.

2 Answers 2

2

Here's the question with the same problem (didn't vote for closing yours as duplicate since the older one does not have an accepted answer):

The solution there is:

  1. Start by referencing your existing MySQL database in database.yml.
  2. run rake db:schema:dump to generate the schema.rb file
  3. Paste the create_table methods from your schema.rb into a new migration, and Voila!

To avoid any inconsistencies you can always check whether the table is already exist, and, if yes, just skip the migration altogether:

class CreateTable < ActiveRecord::Migration
  def change
    unless ActiveRecord::Base.connection.table_exists?('table_name')
      create_table :table_names do |t|
        # some columns
      end
    end
  end
end
Sign up to request clarification or add additional context in comments.

6 Comments

Seems like this would fail in prod because it would try to create those tables and they would already exist, no? I added a sentence to clarify that we have to do this without losing data.
@williamcodes you can always use ActiveRecord::Base.connection.table_exists? 'table_name' to check and not run the migration
that makes sense. You mean use it as a conditional in the migration file to prevent it from being run twice, right? Can you add that to your answer?
so to clarify, db:schema:dump generates its schema.rb from the tables that are actually in the MySQL database, so we have to run this dump while connected to prod, correct?
@williamcodes right, db:schema:dump creates the schema.rb based of database. But you do not have to be connected to production while running it as long as you have tables (even empty) in your local db - it only cares about table and columns, not about contents
|
1

After backing up the content of the tables which are not present in the migrations, you could:

  • DROP those tables;
  • Create migrations for each of the dropped tables;
  • Run each of the created migrations;
  • Manually repopulate the tables that were created with the migrations them.

That way you'll have no problem with the migrations. If you have no relevant data on them just DROP them right away.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.