Can I deploy to Heroku without destroying existing database? Ruby on Rails - 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.

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.

"ActionView::Template::Error (Unknown primary key for table" after trying to push local database to Heroku

For a Ruby-on-Rails app that I'm hosting through Heroku, I recently downloaded a backup, restored it locally and then added data to the database from outside sources. That all worked fine.
After the updated database was pushed to Heroku using heroku pg:push <localdbname> HEROKU_DATABASE_URL --app <appname> the app was working fine and I could see the data that was newly added.
However today when I tried to log in to the app on Heroku, I was getting error messages. In my log file I saw this error:
ActionView::Template::Error (Unknown primary key for table ...
According to this SO post: Getting "Unknown primary key for table" while the ID is there
one user was able to get around this problem by resetting and pushing the database to Heroku several times. However, that hasn't worked for me. I've tried to reset and push the database at least 4 times now.
One possibility is that my local postgres database is using version 9.6 and the app is using version 9.4. The Heroku database is a Hobby-Basic database. There is documentation from Heroku on how to upgrade the Postgres version but it's not totally clear from their example what I would need to do. I'm guessing that I basically need to create a new database, copy the data from the old to the new and then destroy the old. Has anyone done this before? Is there a fee associated with doing so? And has upgrading the version of Postgres remotely fixed this issue for other people?
I have ran into similar issues before. I was creating a postgres database outside of rails in RazorSQL. I imported data from outside sources and when I ran it locally everything worked fine. When it came to deployment I ran into all sorts of issues.
I created tables outside of rails thus no migrations were created. I had to recreate the tables by deleting the current model and generating a new model which is a copy of the old one only this time a migration is created for example:
rails generate model ad name:string description:text price:decimal
seller_id:integer email:string img_url:string
I needed to import data from the database I had already created and before I did anything I actually created a seed file using this gem https://github.com/rroblak/seed_dump. All I had to do when I created the model again (remember to delete the model and recreate it) was run rake db:seedand it pulled the data in.
3.The last thing I had to do was insert the assocations in the models for example in a owner model putting in has many: customersto connect the customer model.
Another scenario was I ran a query in RazorSQL and generated a new table from the query and imported it into postgres. The problem was it was only a table from results thus it did not have a primary key. I had to manually create that in postgres using ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY; This gave me an auto incrementing primary key field and I have to give credit to this answer which helped me https://stackoverflow.com/a/2944561/7039895.
Hope this helps.
According to the docs, you several choices of how to upgrade your database. pg:copy and pg:upgrade.
In your case, I recommand pg:copy: this is easier but required your database to be "off" while your doing the upgrade. This should not be an issue since your database is not currently working.
pg:upgrade should only be used when the downtime required for a PG copy
upgrade is unacceptably long for your business.
Upgrade with PG copy: (All the steps are explain in depth in the link)
Provision new database
You need to create a new database, it will be automatically using the last version of postgresql for heroku (in your case 9.6)
heroku addons:create heroku-postgresql:standard-0
Prevent new database updates
Stop you current database from writing mode to avoid corrupted data while copying to the new
heroku maintenance:on
Transfer data to new database
You need to copy all the data from the old DB to the new.
heroku pg:copy DATABASE_URL HEROKU_POSTGRESQL_PINK --app sushi
Promote new database
You need to notify heroku that you will use the new DB and not the old one.
heroku pg:promote HEROKU_POSTGRESQL_PINK
Last step: Make application active
Everything should be good by now, just make your DB active so it can save new query.
heroku maintenance:off
As you can see, all the steps are straightforward. Therefore, if upgrading you version of postgreSQL doesn't solve the issue, you can still switch back to the old one before removing it.
Pricing
I think it depends of your subscription already (Hobby, Standard or Premium) https://www.heroku.com/pricing. It may be free, or cheap, but I think it also depends of the size of your DB.
To be sure it won't cost you too much, I'm sure you can ask directly to Heroku support https://devcenter.heroku.com/articles/paid-support.

Does a capistrano rollback undo migrations?

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.

What if we mistakenly deleted some migration file..?

I have deleted some migration file mistakenly. Those files are already migrated.
If I am creating migration with same name, and fire rake db:migrate command it is showing me message that Table already exist. Is there any way to regain those files?
please help..
You will find information about previous migration in config/schema.rb
There is no need of keeping old migration files if all databases (developers, staging and production) have been migrated. Even if you did not delete the old files, they would not prevent you from getting a error message if you try to create a duplicate table.
I am relatively new to RoR. However, I'm a bit concerned that losing this file will present some problems if you aspire to host your app on a server other than the one it is currently hosted on. For example, if you had a mind to host the app in Heroku, you would need to run your migrations in that environment.
If you are not terribly far along with your application, it would be best to start over, take care not to delete your migrations, and put your app under version control so that you will have a fallback should you run into this problem in the future.

ruby on rails - git repository, database handling

I am currently using Bitbucket and am handling a Ruby on Rails repository across users. By default, when one user pushes the repository(default command - git push origin master -entire rails folder), I assume that the db also gets pushed to bit bucket, right?
When a second user downloads the repository off git, shouldn't i expect all the db files to also get downloaded?
Is it necessary for the second user to run rake db migrate commands again after downloading the file?
In the specific case above, I am the second user and I get the following error message upon downloading the repository off BitBucket, while the file run perfectly on the uploaders computer:
ActiveRecord::StatementInvalid in StaticPagesController#home
Could not find table 'users'
I want to make sure that both of us are working on the same DB and are not working in parallel on different datasets.
Data in your database will reside only in database. It will not be in git repository. The repository contains database config files and migration files to create databases on the fly. Again, it doesn't contain data.
If you want to work on the same database, I would look into using Amazon AWS RDS. Setting up RDS is not undoable, but it's not trivial enough for me to expound on exactly how you do that here.
I guess you are new to Rails. The way Rails handle database in development is :
with database structure:
You maintain the structure through migrations file.
Yes, if you pull new code that does contain new migration file, you
need to run rake db:migrate. You will notified if you don't.
with database data:
In development, you can maintain data to test through seed file. You can watch this great screencast here: http://railscasts.com/episodes/179-seed-data
Better, you should use seed_fu gem https://github.com/mbleigh/seed-fu

Resources