ActiveRecord PGError on Heroku not locally - ruby-on-rails

I am getting an ActiveRecord PGError on Heroku not locally. The error message from the Heroku Logs is:
ActiveRecord::StatementInvalid (PGError: ERROR: column items.user_id does not exist
LINE 1: SELECT "items".* FROM "items" WHERE ("items".user_id = 4) OR
This code works locally (SQLite) but not on Heroku (postgresql) so I have been reading about the differences. At first I thought that it was a case issue as I recognised that it should be User_ID -- but now I'm not sure, it's something about "items" that isn't quite right and I can't work out exactly what it is.
As I said this works absolutely fine on my local machine, it's only on heroku and postgres that the problem comes up.
Thanks in advance.

It appears that your database does not have the 'user_id' column in the items table. This could be because your migration has not been run recently, or perhaps you have edited an existing migration rather than making a new migration to add this column.
Do you care about your data on heroku at the moment? If not you can use Taps to take whatever you have in your local database and set Heroku's database to a (virtual) synchronized copy of it. On your local machine from your project's directory:
heroku db:push
This will wipe your heroku database so use this wisely.

Try restarting the app, using the following command:
heroku restart

It was a case issue after all - postgres does (I believe) a downcase on everything before sending it to the db -- my user_id was actually called, inexplicably, User_ID; after migration everything is working -- thanks to those that helped.

Related

"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.

Why does order of migrations matter in Heroku Postgres but not local Postgres database?

I was having a hell of a time earlier trying to figure out why Heroku couldn't run my migrations. It kept complaining that a reference did not exist.
For my first migration, I referenced a table that hadn't been created yet using a foreign key. In order to solve this problem, I had to arbitrarily modify the timestamps of the migration files so that no table would be created before a table it depends on (references).
Amazingly, this solved the problem with running the migrations on Heroku and they eventually ran without error. Also, the migrations would run perfectly on my development machine, even with the tables that have dependencies being created before the referenced tables exist.
Why did it work on my local database and not on the Heroku database? Is there something I can do next time this happens? It seems really ridiculous to have to always create migrations in order of their dependency in order to please Heroku. I must be missing something, no?

Heroku throws error where local host does not

I have a rails app running on heroku. Locally everything works fine. However, upon pushing to heroku there is an error.
The logs state this:
app/controllers/orders_controller.rb:7:in `create'
ActiveRecord::UnknownAttributeError (unknown attribute: ammo_id):
Started POST "/orders?ammo_id=4" for 96.235.177.110 at 2014-08-09 00:03:09 +0000
I.e. that this is an error in my orders_controller on line 7. This is line 7:
#order = #cart.orders.build(ammo_id:params[:ammo_id])
Locally this run perfectly. However, on heroku it does not. I changed that line to:
#order = #cart.orders.build(:ammo_id => params[:ammo_id])
And now it works on heroku. So my question is, why does the first syntax not work on heroku? Does it have to do with versions?
Attributes
Having just answered another question like this, I'd say the problem is almost certainly to do with your Heroku DB not having the attributes it needs to run
The issue here is that your Rails development DB & Heroku production DB will be completely different, and as such, you need to make sure you have migrated your Heroku db as you have your local one
The way to fix it will be to run the following on your local machine:
$ heroku run rake db:migrate
--
Whenever Rails throws ActiveRecord::UnknownAttributeError - it means Rails does not have access to the particular attribute on your model class.
To understand this, you must remember that Rails is basically a series of classes which load with each request. These classes, as per the object-orientated structure, are populated by a series of attributes. These attributes, in the case of Rails, are pulled from the database -- meaning if your application cannot find specific attributes, it simply means the database doesn't have them
To fix this, you have to ensure you have the required columns present in your db. The most common instance of this issue is a lack of foreign_key in your various models
It might have to do with Database Migrations. Make sure you run heroku run rake db:migrate <your branch stuff here> after every push so that our schema updates to your new models.
Also,Your heroku may be defaulting to an older version of ruby. The => syntax for hashes was the default in older versions of ruby. But now {key: value} is a new acceptable format. Though this is very unlikely.

How do I exclude data from local table schema_migrations from being pushed to Heroku DB?

I was able to push my Ruby on Rails app with MySQL(local dev) to the Heroku server along with migrating my model with the command heroku rake db:migrate. I have also read the documentation on Database Import/Export. Is that doc referring to pushing actual data from my local dev DB to whichever Heroku's DB? Do I need to modify anything in the file database.yml to make it happen?
I ran the following command:
heroku db:push
and I am getting the error:
Sending data
2 tables, 3 records
!!! Caught Server Exception | ETA: --:--:--
Taps Server Error: PGError ERROR: duplicate key value violates unique constraint
"unique_schema_migrations"
I have 2 tables, one I create for my app and the other schema_migrations. The total number of entries among the 2 tables is 3. I'm also printing the number of entries I have in the table I have created and it's showing 0.
Any ideas what I might be missing or what I am doing wrong?
EDIT:
I figured out the above, Heroku's DB already have schema_migrations the moment I ran migrate.
New question: Does anyone know how I can exclude data from a specific table from being pushed to Heroku DB. The table to exclude in this case will be schema_migrations.
Not so good solution:
I googled around and someone else was having the same issue. He suggested naming the schema_migrations table to zschema_migrations. In this way data from the other tables will be pushed properly until it fails on the last table. It's a pretty bad solution but will do for the time being.
A better solution will be to use an existing Rails command which can reset a specific table from a database. I don't think Rake can do that.
Two possible options:
The heroku gem and the taps gem (which it uses to synchronize databases) are both open-source - you could fork them, alter the taps client API to support excluding tables from a push, then alter the heroku gem to use that new option.
You could write a wrapper script that uses pgdump to backup the schema_migrations table, drops that table, heroku pushes the database, then reloads the table.
This is kind of a guess based on the error you're getting, but push looks like it grabs the schema and the data. I'd try push to an empty database.
I've just deployed a Rails 3 beta app to heroku on their new bamboo server. I can now upload data from my local dev machine to the heroku database by doing:
heroku rake db:fixtures:load test/fixtures/my_model.yml
The data is then properly propagated in the Heroku database. Even though I specified a specific data file, it automatically pushes data from my other yaml files. It probably has something to do with my model relationships.
If your databases are out of sync you can always reset the Heroku database before pushing using
heroku db:reset
To push/pull from specific tables
heroku db:pull --tables logs,tags
http://blog.heroku.com/archives/2010/4/21/supporting_big_data_part_1

Why is rake throwing this Rails migration error?

I have two machines... a development machine and a production machine. When I first brought my rails app onto the production server, I had no problem. I simply imported schema.rb by running rake db:schema:load RAILS_ENV=production. All was well.
So, then on my development machine, I made some more changes and another migration, and then copy the new application over to the production machine. I then tried to update the database by running rake db:migrate RAILS_ENV=production. I get the following error:
"There is already an object named 'schema_migrations' in the database."
I'm thinking to myself, ya no kidding Rake... you created it! I ran trace on rake and it seems as if rake thinks it's the first time it's ever ran. However, by analyzing my 'schema_migrations' table on my development machine and my production machine you can see that there is a difference of one migration, namely the one that I want to migrate.
I have also tried to explicitly define the version number, but that doesn't work either.
Any ideas on how I can bring my production server up to date?
Update:
Let me start off by saying that I can't just 'drop' the database. It's a production server with a little over 100k records already in it. What happens if a similar problem occurs in the future? Am, I to just drop the table every time a database problem occurs? It might work this time, but it doesn't seem like a practical long term solution to every database problem. I doubt the problem I'm having now is unique to me.
It sounds like the 'schema_info' table and the 'schema_migrations' table are the same. In my setup, I only have 'schema_migrations'. As stated previously, the difference between the 'schema_migrations' table on the production server and the development machine is just one record. That is, the record containing the version number of the change I want to migrate.
From the book I read, 'Simply Rails 2', it states that when first moving to a production server, instead of running rake db:migrate, one should just run rake:db:schema:load.
If it matters, I'm using Rails version 2.1.
This is a guess, I admit: I think that because you first ran db:schema:load instead of db:migrate in your production environment, you got the structure of your db, but not the data that migrate populates into your schema_info table. So now, when you run migrate in the production environment, there is no data in schema_info which is why migrate believes that it hasn't run yet (because it hasn't).
That said... you say that you have looked in the "schema_migrations" table, and that there is a difference of one version from dev to production... I haven't heard of that table, although I'm a few months behind on my rails version. Maybe you could try creating a "schema_info" table in the production environment, with a single "version" column, and add a row with the version that you believe your production environment to be on.
If you get "There is already an object named 'schema_migrations' in the database." error message then I suspect that you are using MS SQLServer as your database? (As this seems like MS SQL Server error message)
If yes then which ActiveRecord database adapter you are using? (What is your database.yml file, what gems have you installed to access MS SQL Server database?)
Currently it seems that Rails does not find schema_migrations table in production schema and therefore tries to create it and this creation fails with database error message. Probably the reason is upper/lower case characters in schema_migrations table name - as far as I understand MS SQL Server identifiers are case sensitive.
Depending on the system used in production, I have seen instances where the below does not work:
rake db:migrate RAILS_ENV=production
But where this one does work:
RAILS_ENV=production rake db:migrate
Quirky, I know, but it's worth trying it to see if it makes a difference.
Regarding your update:
I don't understand what the difference is between your production schema_migrations and the dev version. Is there a record in both tables (there should be just 1 column, "version", right) or is there a single record in the dev DB and zero records in production? If there are zero records in the production table, then do this:
ActiveRecord::Base.connection.execute("INSERT schema_migrations (version) VALUES(#{my version number that production is supposedly on})")
Alternatively, you could try dropping the schema_migrations table totally on production:
ActiveRecord::Base.connection.execute("DROP TABLE schema_migrations")
Then, re-running rake db:migrate RAILS_ENV=production. That will run migrations from starting from version 1 though, which is probably not what you're after.
Alternatively alternatively, you could start an IRB session in your production environment, do either a "require" or "load" (I can never remember which, or if it matters) of the migration file that you want to load, and then call MyMigrationClass.up. You would need to manually set the version number in the schema_migrations table after that, as you would still have the problem going forward, but as a quick-fix type of hack, that would work.
I would just drop the DB, add it again and run rake rb:migrate. Brad is correct that when you ran the schema load, it didn't put any records in the schema_migrations table.
This is more complicated of course if there is data you can't lose on the production server. You could get the rake backup tasks (not sure if that is part of core or not) and then run rake db:backup:write on your production database, and then after you get the migrations up to date on production, run rake db:backup:read.
schema_info is from an old version of Rails. schema_migrations is the new kid on the block. You should be able to remove the schema_info table as it'll no longer be used. You'll probably want to search for any issues associated with this name change.
rake db:schema:load will load the database structure from schema.rb. This file is the current representation of the database structure. It's used when you have an empty schema (database) that needs all the tables and indexes creating. It saves you having to run all the migrations. If you have an existing production database with data in, you don't want to run it. As others have said that would be bad!
I know this post was some time ago, but I stumbled across it and it hasn't really been answered. As it comes up on google, here goes.
When you did a rake db:schema:dump (or when this was done for you by the build scripts) it will have put the definition of the migrations table into the schema.rb. At the end of the script, the process will try to create the table again, however it obviously exists already. Just remove the migrations table from the schema.rb before running rake:schema:load and there will be no error message.
You will need to set the version number in the migrations table to subsequently run migrations. So it is important to know what version your schema.rb relates too, or delete all the old migrations (they're safely in your SCM right?)
rake db:migrate RAILS_ENV=production
Use the db:schema:load task just for the first creation, incremental changes should be migrated.

Resources