I have a rails app that was working fine with sqlite but upon switching over to postgre I’m having an issue with this query:
User.find(1).ratings
Querying for just a works, e.g.
User.find(1)
produces
SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]]
however if I append ratings like so:
User.find(1).ratings
produces
User Load (1.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]]
Rating Load (0.9ms) SELECT "ratings".* FROM "ratings" WHERE "ratings"."user_id" = 1
PG::Error: ERROR: operator does not exist: character varying = integer
LINE 1: ...CT "ratings".* FROM "ratings" WHERE "ratings"."user_id" = 1
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
: SELECT "ratings".* FROM "ratings" WHERE "ratings"."user_id" = 1
ActiveRecord::StatementInvalid: PG::Error: ERROR: operator does not exist: character varying = integer
LINE 1: ...CT "ratings".* FROM "ratings" WHERE "ratings"."user_id" = 1
^
Whether a pass the :id as an int or string it still produces the above error. The models are set up so :ratings belongs_to User which has_many :ratings. Any ideas? Thanks in advance.
Versions: Rails 3.1.1, Ruby 1.9.2, devise 1.5.1
This error
usually means that you’re trying to compare two different data types for equality. Some platforms will let you do that by silently coercing one to the other. SQLite will, and it will let you do a lot of things that are not compliant with SQL standards. PostgreSQL usually won’t allow comparisons like this. Since it prints
in the error message, it’s telling you that, although you supplied an integer (
1), the column ratings.user_id is actually a varchar().SQLite isn’t SQL. Here I use the universal data type “wibble”.
SQLite is happy to let me insert “Wibble” into an integer column. That should at least give you pause, if not nightmares.
PostgreSQL is free and available for many platforms. If you’re anticipating deployment on Heroku, I can’t see any reason not to install PostgreSQL and develop against it instead of using SQLite.