How to rollback to beginning and recreate/rebuild new migrations - ruby-on-rails

So this is my first real Ruby on Rails project. I've learned my lesson -- I didn't make all changes using migrations so things are a bit messed up.
What's the best way to start over with new migration files and rebuild the schema, etc? My project is too far along to rebuild the entire project, but not far enough along to where I care about losing the migrations I have thus far. I also don't mind losing the data in the database. I was trying to rollback to the beginning but some of it is failing.
I know this is a bad state to be in, but lesson learned.
EDIT:
I just deleted all the migrations files and rebuilt the schema file with db:schema:dump.
I assume this puts me in a clean state with my existing database, just lost migrations.

if you want to migrate some steps back you can
rake db:rollback STEP=2
That command will migrate your database 2 migrations back.
If you need more help with rake commands, jus type
rake -T
That command will list all the tasks you have in you application.

If you are not concerned about losing data then do
rake db:purge
It should just drop your database

Your schema.rb file should contain the actual schema from your database. You could use it as a starting point to create you migrations. You could create a new migration for each table with the :force => true parameter to overwrite the old table. Afterwards you could just delete the old migrations (you would probably also need to delete their entries from schema_migrations table).
Another options would be just updating the old migrations to match your current schema.

Related

How do I fix my database when I've deleted the current migration file?

My problem is that I at some point was doing some spiking and I migrated my database with a migration that I had created in the spike branch. Then I switched back to my master branch(I never committed the migration). Now that migration is perpetually in my database and this is making it impossible to migrate my database.
when I run
ActiveRecord::Migrator.get_all_versions
in the console my deleted migration file timestamp is in this array. I would like to remove this version from the migrator. Also I cannot drop the database.
If the database can be blown away, then the quickest way would be to drop the database, create it afresh, and reapply the migrations, with the following steps:
rake db:drop
rake db:create db:migrate
If the database has useful information & can't be blown away, then it is tricky. Only possible option would be to go to the database level, and undo the changes made by the migration.
Figure out which tables/columns were added/deleted in the migration, and then run sql scripts to reverse those changes.
In addition, delete the specific row corresponding to this migration from schema_migrations table, with the following query:
delete from schema_migrations where version = '201503......'

Ruby on Rails Migrations and Moving Up and Down Basics

I took a couple courses on rails but a few things are unclear to me regarding migrations:
1.) If I generate a migrations and run it, no matter how few operations I perform does rails still create a whole entirely new version of my schema? Is there anyway to view each version's schema before migrations back down?
2.) If I do not define the down method in a migration and I try and rollback, will the rollback do nothing?
3.) Should I delete migrations after I run them?
you dont need to delete the migration file after migrate if you run a migrate to create a table without defining a down method , if you tried rake db:rollback it will revert the last migrate you did , you can see more in here Migration
Migrate does incremental changes to your schema. It knows (unless you stuff it up) what state your schema is in and runs those migrations that haven't yet been run.
e.g. if you do a drop create and migrate and then migrate a second time, the second one does nothing, because they've all be done.
No down indeed means rollback will do nothing.
The only time you should delete a migration is if you are completely undoing a change. ie you added a model and then decided you didn't need it.
Any other approach would mean you couldn't achieve your schema from scratch.
e.g. you add a model and migrate
then you realise you need a relation and do that. delete the migration that added the table, things go horribly wrong.

Why is db:reset different from running all migrations?

In section Rails Database Migrations of Ruby on Rails Guides, there is one line saying that
The db:reset task will drop the database, recreate it and load the current
schema into it. This is not the same as running all the migrations.
Can anyone tell me where exactly they are different and why it is more error prone to replay the migration history?
I'm fairly new to Ruby on Rails. Thanks in advance.
The schema file contains the current structure of your database. When you load it, you are guaranteed to have the exact schema in your db that is in the file. Migrations were designed to make incremental changes in the database. You may add a table, then some columns, and then remove the table in three separate migrations. There's no need to go through all this when the schema already knows that the table no longer exists.
On why they are error prone, I'm not totally sure. The one thing I can think of is that migrations can be used to make changes to data and not just the structure.
Running rake db:reset will rebuild the structure of your database from schema.db, which essentially works as a cached version of your migrated database structure. Running all your migrations, on the other hand, applies the migrations one by one, which may include arbitrary code to accomodate for changes to the database (e.g. prepopulate an added counter cache column).
It can be more error prone to replay the migration history, since it is the product of changes to both the structure and data of the database. If the developers haven't been careful, it might not apply cleanly to a fresh environment (e.g. the migration assumes an old version of a model). On the other hand, schema.db can get out of sync if you edit a migration once you've migrated (a useful trick to avoid migration explosion during development). In that case, you need to run rake db:migrate:reset.

Generate a migration file from schema.rb

I'm looking to generate a migration file from the schema.rb. is it possible?
I have many migration files at the moment and would like to combine everything into one master migration file.
I also think i may have accidentally deleted a migration file at some point.
thanks for any help
You could copy and paste schema.rb into a migration and back-date it (e.g. change the date) so that no existing databases will run it. After you create this migration you can delete all your old migrations.
I disagree with Andrew that you should never delete migrations. Migrations break unexpectedly all the time based on model classes changing and it is very non-trivial to fix them. Since I'm sure you are using version control, you can always look back in the history if you need them for reference.
There's no need to do this. For new installations you should be running rake db:schema:load, not rake db:migrate, this will load the schema into the database, which is faster than running all the migrations.
You should never delete migrations, and certainly not combine them. As for accidentally deleting one, you should be using a version control system, such as Git.

My rails migrations won't run, and I can't deploy my rails app. How can I start over?

At some point in my rails development I started making database changes (e.g. dropping or altering columns/tables) without using rails migrations. So now I get errors when I try to deploy my rails app from scratch.
blaine#blaine-laptop ~/tmp/rbjacolyte $ rake db:migrate
(in /home/blaine/tmp/rbjacolyte)
== AddHashToTrack: migrating =================================================
-- add_column(:tracks, :hash, :string)
rake aborted!
An error has occurred, all later migrations canceled:
Mysql::Error: Table 'jacolyte_dev_tmp.tracks' doesn't exist: ALTER TABLE `tracks` ADD `hash` varchar(255)
(See full trace by running task with --trace)
How can I sync my production and development environments with migrations after I've mucked it up by using raw SQL? I want to deploy my rails application without database errors, and I don't want to start from scratch.
The data in the production and development environments match, but the migrations fail. I want a way to 'start from scratch.'
Could I simply delete all of the migrations that I have, and then just start using migrations from now on?
The shortcut way: manually add an entry to schema_migrations for a timestamp that represents a baseline. You can add migrations after that and as long as they don't make any bad assumptions about the db schema they should be able to run just fine. You won't be able to migrate backwards, but that's not a huge problem.
The bigger problem is that you won't be able to make a DB from scratch, which gets to be a pain longer term.
The fix for that is to delete all your existing migrations and create a new one that creates the existing schema. Manually delete everything from the schema_migrations table and put in an entry for this one new migration. After that, you can create new migrations that build on this new baseline and they should apply just fine. You should be able to bootstrap new databases in the normal fashion.
As long as your direct SQL is contained in Rails migrations, there's no problem with using it. Just make sure you implement both the #up and #down methods and you should be good. We've actually taken to using raw SQL as a best practice to avoid problems when models are changed later on. Something like
Foo.create(:name => 'bar')
seems innocuous, until the User model is modified to have
validates_presence_of :baz
At which point the new migration will run against an existing database, but that earlier migration that created the table and added the dummy entry will fail because User fails validation. Just using
execute("insert into foos (name) values ('bar')")
will work fine as long as the later migrations properly populate any new columns they add.
Maybe you could just get rid of all your current migrations, and use rake db:schema:dump to create a new schema.rb file, and manually edit your production database to reflect the changes you've made so far?
I like Veeti's suggestion, with a modification: rake db:schema:dump, then move that file to your development machine. Flatten your Rails migrations so far (see this SO thread on that), get rid of most of your migrations, and re-work your migrations to work, given your new schema.
Get this working on your dev machine, commit and deploy.
If the existing production data is compatible with the development database schema, then I would:
Dump the production data to a file using a program such as mysqldump
Drop the production database
Recreate the production database
Run the migrations against the production database, specifying VERSION=0
Import the production data from the file created at step one
If the schemas aren't compatible then you might be able to follow this process but you'll have to edit the SQL in the file created in the first step to take account of the schema differences.

Resources