how to create a migration file for columns that already exist - ruby-on-rails

I created a migration and ran it in a git branch but then did not merge the branch. However, the db columns from that migration continue to exist and I in fact still need them. Since there's no migration file for them (because I didn't merge the branch), I created a new migration but obviously can't run it, because the columns already exist. I therefore renamed the file by giving it a number that made it seem as if it was an earlier migration -- I thought Rails would think that the migration had been run if I changed the number on the file. However, that hasn't worked. Now anytime I run a migration, it's getting aborted because I have this migration file in it that hasn't run but for which the columns already exist. I can delete this file but that won't help me when I push to production.
What do you do in this situation?
I'm using postgres if it matters

rake db:rollback
Then generate the migration in your other branch and
rake db:migrate

Rails checks if a migration has already been run by comparing the migration numbers of the files from db/migrate/ directory with the numbers it finds in the schema_migrations table. If you want to pretend that the migration has already been run, just manually insert the migration number into this table.
However, this is just an ugly workaround, it definitely should not be something to use often - and never use it in production.

Related

Can I manually create migrations for production in Heroku, Ruby on Rails?

I have created an application with Ruby and Rails. The thing is that when I was develpoing it, I had some problems with the migrations, because I created them but with a wrong syntax. What happened is that I deleted some of the files because sold migrations that didn´t work had the same name than the new ones, but in the middle of that I accidentally deleted some of the migrations (obviously after running rails db:migrate) that the project uses actually. So for instance, i have the Service table, which is related to the Reservation table because Service has reservation_id, but i don´t have the migration file that says AddReservationIdToService.
So now I want to use Heroku for production. the thing is that O have to change to postgresql because Heroku doesn't support sqlite. So i have to run the de:migrate again to create the tables and relationships in the new DB, but I need the files that I explained that I deleted. The question is:
Can I create the migrations manually, so when i run db:migrate for postgres the full structure of the database is created without lacking relations?
You don't really need the migrations to recreate the existing DB -- in fact it's not a good idea to try for a couple of reasons (including the missing migration file problem you encountered). You can simply run:
bin/rails db:schema:load
to populate a new database from the existing schema. If for some reason you haven't got a db/schema.rb checked under version control you can run:
bin/rails db:schema:dump
against the sqlite version to re-create a fresh schema file from the database.
You can also keep your migrations list tidy by occasionally zapping really old migrations, since all the cumulative changes are captured in the schema file.
Yes, you might create another couple of migration files.
Certify you have now the tables you wish locally with your sqlite. Draw these table in a piece of paper (or where it be the best fr you), then check this official API documentation of Rails.
Delete all migrations made before and create another according to the tables you drew.
The workflow is gonna be like:
1) "I need to create a table called Reservation, where is it shown on the documentation?"
2) "I need a table called Service, where is it shown on the documentation?
3) "I need to add a column with a foreign key to service named reservaton_id, how does this documentation says it?
For all this steps above, create the correspondent migration file as you normally have done.
The main difference here is not to run the migration locally. Instead, push your new version app to your heroku remote branch and there you run the migration, like:
heroku run rails db:migrate
Remember to not run this same migration locally because you already have these tables locally.
The last two advise is:
1) If your migration doesn't go as you expect, don't delete the migration file. Instead, run rails db:rollback and try again.
2) Keep tracking your migration files on the same branch of your version control.

Rails lost migration file issue

2 months ago, one of my migration files has been removed. The thing is when I rake db:migrate my database in localhost the migration is missing. I can Not create a new migration because the production database was migrated with the missing file. So everytime I import the production database in local and I run a migration it says:
Field already exists....
I saw some comment which says I should modify the schema_migrations table with the corresponding version of the migration file.
Do you have any deeper explanation about this issue.
Thanks
the schema_migrations table holds all the version numbers of all the migrations that have been run, or that the system thinks have been run at least. When you do rake db:migrate, rails looks at all the files in db/migrate, and ignores the ones whose numerical prefix is in schema_migrations.
So, if you have a migration that has actually already been run, but the system thinks it hasn't, you just need to add its version number into schema_migrations.
Open the relevant database console, and type
insert into schema_migrations (version) values("<the number from the start of the migration file>");
obviously, replace the part in < > with the proper number.
Then, db:migrate will no longer try and run that migration.

Rails with existing database keeps saying migration pending

I'm trying to make a new rails project with an existing database.
I create the projects, configure the database.yml and can successfully do a db:schema:dump
This is all based on what I read on this site
http://blog.joelberghoff.com/2013/02/06/ruby-on-rails-tutorial-creating-a-rails-instance-from-an-existing-mysql-db/
And a few others.
After I do the dump, I copied the schema.rb into db/migrate and renamed to 001_createdatabase.rb as indicated in his tutorial.
Everything seems fine. However I cannot run the site as it tells me i have migrations pending. and the db:migrate:status indicates its that 001_createdatabase.rb that I created.
So based on that:
Was creating that 001_createdatabase migration from the schema.rb the right thing to do?
If it was how do I get rails to understand that it doesn't need to run that one as its already done?
Where does rails check to see if it has pending migrations. Obviously it must check the db/migrate folder and compare it to what?
Thanks
It would seem that in order to get credit for having run the migration, you need to actually run the migration. The migration, 001_createdatabase.rb, represents the migration that will take you from having an empty database -- no tables, no data -- to having your first version of the database. When you run rake db:migrate, rails checks to see if every file in the db/migrate directory has been run by looking for the numerical part of the migration file name in the schema_migrations table.
In your case, you've not run the migration, there is no entry in the schema_migrations table, so rails thinks, rightly, there is a migration to run.
To fix the issue, you can put the record that the migration has been run into schema_migrations or actually run the migration. You may need to create the schema_migrations table, rails will create it as needed.
If you want to run the migration, either drop your database (or create a new one -- you can drop the old one when this works), and point your rails application to the new database. run rake db:create and rake db:migrate. When it completes, you should have a new copy of your database, but one that has been created by the rails migration process. The schema_migrations table should have a record with 1 in the version column.

Typo in rails migration file

Folks,
I have a situation where I created a rails migration file which updates the value of an attribute in a model. I ran this migration on several production deployments and then realized the table was never updated due to a typo. What is the best practice to fix this, should I be updating my current migration file with the fix and commit it and then re-run the migration OR should I create a new migration file and remove this migration.
If you ran a migration and it succeeded and then you update your current migration file and try to re-run the migrations, Rails won't update your schema because the migration version will be the same as the current db version.
If you do a rake db:migrate:status you should be able to see the list of migrations and the ones that have been applied or not.
Based on that, if your migration says status: down it means that it still hasn't been applied to the database.
If it has already been applied to the db you can have a number of options.
rake db:rollback update your file then re-run that migration
Create a new file that fixes the typo. Note that even removing the migration with the wrong data won't fix your database depending on what you did to the table and how you fixed it on the new migration.

Heroku rake db:migrate

Heroku is telling me that there are migrations that haven't been run, when clearly they have been. It looks like it is behind one migration. How could I solve this problem.
When I run rake db:migrate it tells me rake aborted Mysql2::Error: Duplicate column name. I know these fields have already been created, also pretty sure that migration ran, as those fields don't exist in any other migration and rake db:migrate runs just fine on my local system.
How can I fix this? I think Heroku just didn't realize it already ran that migration. How can I tell it "you already ran migration xxx"?
That probably means you ran it once, but it failed; table alterations in mysql are not transactional, so you can get left in a bad state. Some of the changes may have run, but not all of them.
The only thing you can do is determine which parts already ran, comment out those line in the migration, commit and push and run the migration, bypassing the parts that already ran.
If a migration is incompletely applied, do one of the following:
Use the dbconsole to undo the changes that were applied and then run the migration again, or
make the remaining schema changes manually using the dbconsole and then insert a record into the schema_migrations table.
Depend on what types of changes are in the migration script, you'll need to decide which of the above is easiest. If the changes already applied are destructive changes, such as dropping a column or table, you could recreate the column or table so that the migration will be able to run. If the remaining changes are simple to translate into SQL, then that might be easier.
Inserting a record into the schema_migrations table will allow the app to think that the migration was successfully applied. Do this only if you're absolutely satisfied that the migration changes were completely applied. It has one column, version, which will need to contain the numeric part of the migration filename.
http://api.rubyonrails.org/classes/ActiveRecord/Migration.html
http://guides.rubyonrails.org/migrations.html
Finally, this is an example of why you should use Postgres instead of MySQL. Postgres is able to roll back (most) schema changes in a transaction, so you wouldn't be left with a half-applied migration.

Resources