Does a capistrano rollback undo migrations? - ruby-on-rails

I'm new to this. I have a production server and need to deploy the latest version of the application from github, so I'm using Capistrano.
The newest release makes some changes to the database and hence has a bunch of migrations, so I'll be deploying it with deploy:migrate.
So my question was, if I add some data to the new columns created (it doesn't change any of the existing columns in the tables, just creates new tables and columns) and then want to rollback, then will cap deploy:rollback reverse all the migrations as well? Is the data in those new columns erased and the database back to the previous state (assuming I didn't make any data change except to the new additions in the db)?
Thanks!

No, it will not. You would need to manually run the down part of those migrations via rake and then roll back.
However, if your current app won't be affected by the new rows it won't hurt anything.

Related

Rails Migrations Convention

I've started working with rails recently and I have noticed that during development you can end up with a lot of migration files as your ideas change and your database with it. Is there a convention in rails to avoid accumulating a lot of migrations and deleting redundant ones (such as one migration adding a table and then the next deleting it)? Or, is it preferred to keep all your migrations and never delete them? Thanks.
If you are working on a team it is preferred and you always should keep all the migrations.
Suppose you push a migration to Git and later found out that it needs some change. So you revert and delete the migration and create a new one and push the new changes. It works well in your machine. But if somehow your previous faulty migrations are run by any of your team mate and he pull the new code he will have to run the new migrations which will break the applications in your teammates machine.
But if you are working solo and want to get a bit tidy then you can carefully delete migrations after reverting them (Not preferred).
The primary job of migration files is to alter the database schema. Deleting redundant ones (such as one migration adding a table and then the next deleting it) will not cause any problems and it free up some disk space and slug size.

Can I deploy to Heroku without destroying existing database? Ruby on Rails

I have made quite a large upgrade to my app. I have older version deployed on Heroku at the moment. Problem is that I have added/removed quite few migrations in the process of making my app more modular. I do not want to lose my registered user table that is already up on Heroku while deploying the update. Are there any tips someone can offer on how to preserve my user table while upgrading the app? I do have backup add-on installed but I have no clue what to do with that file.
You should then setup your migrations more carefully since that one, which is last presented on the heroku server. So, when:
you are adding a column, just setup defualt value
you remove the column, you shell export data to (for example) YAML, and store it in the tmp/.
you are reconstructing parts of the colunms by adding and remove some of them, in migration carefully copy required data from older column (prepared to deletion) to newly created ones.
If you're that concerned about deploying I think you might need to declare migration bankruptcy.
Create a new migration that drops the current schema and copy the new database schema into it
Dump out the contents of your database as CSV ( https://coderwall.com/p/jwtxjg/simple-export-to-csv-with-postgres ) or using Rails to dump in some other way (YAML etc.)
Write a Rake task to parse the data dump into your new schema
Set up a new database on Heroku Postgres (this does not delete the old data)
Do a dry run locally to make sure it all works
Promote the new database to DATABASE_URL
Deploy, migrate, run the Rake task
Not very nice and not something you can roll back from easily if it goes wrong.

Rails Migration Order and Git

Since doing migrations with rails + git is type of a pain, a new thorn has sprung..
Before I am doing any harm to my prod DB, would the following situation cause havoc? If so, how would I handle it?
I am working a long-term feature in a separate branch (feature/long-term). This feature is an overhaul of a lot of components and it will take awhile to complete. This feature has new migrations, which were migrated to the localhost DB.
meanwhile, I need to fix/add a migration to the prod system via another branch (feature/quick-fix). This has a migration file with date later than the feature/long-term migration.
The migrations of the quick-fix and the long-term have nothing to do with each other, they do not collide and work on separate tables. It doesn't matter what order they are run.
If I merge feature/quick-fix to master and db:migrate and in a few days/weeks merge feature/long-term the migration files order would be the long-term first.
Would this affect the DB in some way? (the prod DB is important, so I don't want to reset)
What you described is a very common development workflow (especially so in teams with more members) and it's perfectly safe for your production DB.
Rails, as of version 2.1, is smart enough to keep a list of all migrations ever run, instead of just the latest migration version run. This information is stored on a separate table aptly named schema_migrations.
So, if you push a new migration today, say 20140527_quick_fix.rb, and a month after that you push a new (but with an older timestamp) one 20140101_long_term_feature.rb, Rails will still know that the latter was never run in your production environment so during rake db:migrate it will process it, as you would expect. The newest won't be run again of course as the Rails would know that it has already been processed.
From the official documentation:
Rails versions 2.0 and prior used to create a table called schema_info when using migrations. This table contained the version of the schema as of the last applied migration.
Starting with Rails 2.1, the schema_info table is (automatically) replaced by the schema_migrations table, which contains the version numbers of all the migrations applied.
As a result, it is now possible to add migration files that are numbered lower than the current schema version: when migrating up, those never-applied “interleaved” migrations will be automatically applied, and when migrating down, never-applied “interleaved” migrations will be skipped.

Is there a good migration management/clean-up strategy after completing a Rails project?

As I go through the development of an application, in my development environment, I make mistakes and create tables that need to be modified later - as I use the app and see the folly of earlier design decisions.
But when I push to production, I don't want to replicate all those changes when I can just create the 'perfect' table in one migration.
Is there a strategy or something I can use that can help me do that?
If this is the initial push to production, you should be able to copy your schema.rb contents (which should reflect the schema after all migrations were applied) into one giant migration file, and remove all previous migration files.
If your production environment has already been created and the database has been migrated up to a point, then you'll need to use something more intelligent that can bridge the gap between the current state and the latest schema. Unfortunately, I'm not aware of any such project at this time.

My production database is missing some columns. How can I safely restore them?

After making some major modifications to a Rails app that is already in production, I pushed everything to the server, ran my migrations and then discovered major problems.
It turns out that there are 2 database columns that have not been created in my production database by the migrations. When I look through my migrations there isn't one that creates those columns. I'm guessing I made an error with git at some point and have lost those files.
What I want to know is how to safely create those columns in my production database. If I just create a new migration to make those 2 columns, push to production and run the migrations, I presume things will work, but will this cause problems when these migrations get run on my development database with the columns already there?
Try doing this Check if Column exist
Create new migration and add a check whether the column exist or not and if not then create a column using add_column(....).
This will not break your development as well as production code and others using the same git repository will also benefit rather than commenting the operation and uncommenting when its done
Yes this will cause some problem on your develompent database, just comment add_column commands during running rake db:migrate on your development database, and uncomment after that operation.

Resources