2010-05-29 3 views
1

Je suis en train de déplacer une application Sinatra simple à Heroku. Migration du code de l'application Ruby et base de données MySQL existante à l'aide Taps se sont bien déroulées, mais je me fais l'erreur de Postgres suivante:Postgres erreur avec Sinatra/Haml/DataMapper sur Heroku

PostgresError - ERROR: operator does not exist: text = integer LINE 1: ...d_at", "post_id" FROM "comments" WHERE ("post_id" IN (4, 17,... ^ HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.

Il est évident que le problème est lié à une incompatibilité de type dans la requête, mais cela est étant émis à partir d'un modèle Haml par l'ORM DataMapper à un très haut niveau d'abstraction, donc je ne suis pas sûr de la façon dont j'irais contrôler ça ...

Plus précisément, cela semble lancer un appel de p.comments à partir de mon modèle Haml, où p représente un message donné.

Les modèles DataMapper sont liés comme suit:

class Post 
    property :id, Serial 
    ... 
    has n, :comments 
end 

class Comment 
    property :id, Serial 
    ... 
    belongs_to :post 
end 

Cela fonctionne très bien sur mon environnement hébergé local et actuel à l'aide de MySQL, mais Postgres est nettement plus stricte.

Il doit y avoir des centaines d'applications Haml Datamapper & fonctionnant sur les DB Postgres, et cette relation de modèle est super conventionnelle, donc j'espère que quelqu'un a vu (et déterminé comment résoudre ce problème). Merci!

MISE À JOUR: Voir Heroku: Postgres type operator error after migrating DB from MySQL pour la résolution.

Répondre

1

Il semble que post_id soit de type TEXT au lieu de INTEGER. Pour résoudre ce problème, vous devez changer le type de données. Cela a été changé dans la version 8.3, les anciennes versions ont une distribution implicite. Vous pouvez dire PostgreSQL de le faire:

CREATE FUNCTION pg_catalog.text(integer) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(int4out($1));'; 
CREATE CAST (integer AS text) WITH FUNCTION pg_catalog.text(integer) AS IMPLICIT; 

CREATE FUNCTION pg_catalog.text(smallint) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(int2out($1));'; 
CREATE CAST (smallint AS text) WITH FUNCTION pg_catalog.text(smallint) AS IMPLICIT; 

CREATE FUNCTION pg_catalog.text(bigint) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(int8out($1));'; 
CREATE CAST (bigint AS text) WITH FUNCTION pg_catalog.text(bigint) AS IMPLICIT; 

Voir aussi http://wiki.postgresql.org/wiki/Image:Pg83-implicit-casts.sql

+0

Merci, Frank. Je suis conscient que le problème est que les colonnes d'identification ont été définies en tant que texte; la question est * pourquoi *? Sur le back-end MySQL d'origine, ces colonnes sont stockées comme INT et l'application fonctionne correctement, mais pour une raison quelconque, elles sont converties dans le transfert DB. Malheureusement, Heroku ne donne pas d'accès SQL direct à la base de données, donc je ne pense pas que je puisse créer ces fonctions. Ce problème disparaitrait si je pouvais stocker les identifiants comme INT en premier lieu;) Cela semble en fait être un bug Taps et non lié à Sinatra/Haml, donc je vais essayer de reformuler ... Merci encore. – sevennineteen

Questions connexes