2012-05-25 3 views
0

J'ai rencontré des problèmes en déployant mon code rails sur Heroku car mon environnement de développement était défini sur sqllite3 par défaut. Ceci est l'instantané journal suivant:Migration de SQLlite3 vers PostgreSQL (Déployé vers Heroku)

ActiveRecord::StatementInvalid (PG::Error: ERROR: syntax error at or near ":" 
2012-05-25T14:11:55+00:00 app[web.1]: 
2012-05-25T14:11:55+00:00 app[web.1]: LINE 1: ...LECT "records".* FROM "records" WHERE (TIMESTAMP(:order) >=... 
2012-05-25T14:11:55+00:00 app[web.1]: : SELECT "records".* FROM "records" WHERE (TIMESTAMP(:order) >= '2011-05-25 00:00:00' and TIMESTAMP(:order) <= '2012-05-25 23:59:59') ORDER BY created_at): 
2012-05-25T14:11:55+00:00 app[web.1]: app/controllers/records_controller.rb:20:in `index' 

Le fragment de code de mon fichier contrôleur:

opts = {:order => "created_at"} 
opts[:conditions] = (@start_date.nil? ? "" : "TIMESTAMP(created_at::text) >= '#{@start_date.to_s(:db)}'") 
opts[:conditions] += ((@start_date.nil? || @end_date.nil?) ? "" : " and ") 
opts[:conditions] += (@end_date.nil? ? "" : "TIMESTAMP(created_at::text) <= '#{@end_date.to_s(:db)}'") 

A l'origine, j'avais un « DATETIME » où vous avez TIMESTAMP donc je commutées et les problèmes encore obtenir. Le contexte de ce code est que je suis en cours d'exécution d'une requête entre les dates avec le format suivant: 2011-05-25 00:00:00

+0

Je ne suis pas vraiment un gars de Ruby mais il semble que ': order' ne soit pas substitué correctement à' created_at', à la place le symbole lui-même est utilisé. En outre, il suffirait d'écrire '[...] WHERE created_at <= '2011-05-25 00:00:00' [...]' – DrColossos

Répondre

1

Votre created_at devrait déjà être un timestamp donc il n'y a pas besoin de TIMESTAMP(created_at::text) pour essayer de jette-le à timestamp; timestamp(x) ne fonctionnera pas dans PostgreSQL de toute façon. Vous ne devriez pas avoir besoin de ce genre de chose pour SQLite non plus.

Vous finissez par exécutant SQL comme ceci:

SELECT "records".* 
FROM "records" 
WHERE TIMESTAMP(:order) >= '2011-05-25 00:00:00' 
    and TIMESTAMP(:order) <= '2012-05-25 23:59:59' 
ORDER BY created_at 

Vous faites quelque chose quelque part qui change created_at::text-:order dans le SQL. Je n'ai pas été en mesure de reproduire ce comportement, mais je suppose que vous êtes en conflit avec des espaces réservés nommés (c'est-à-dire column = :value plutôt que column = ?) mais c'est juste une conjecture.

Dans tous les cas, si vous débarrasser des choses timestamp(...) et passer à enchaînant vos where appels, vous obtiendrez quelque chose de beaucoup plus agréable:

query = Record.order(:created_at) 
query = query.where('created_at >= ?', @start_date) if(@start_date.present?) 
query = query.where('created_at <= ?', @end_date) if(@end_date.present?) 

Ensuite, vous pouvez query.all ou query.paginate(...) ou autre pour obtenir votre résultats finaux. C'est (à mon humble avis) beaucoup plus joli qu'un tas de querelles de cordes et il devrait fonctionner de la même manière partout.

Si vous devez déployer PostgreSQL (c'est-à-dire Heroku), vous devez développer et tester PostgreSQL. SQLite a des idées étranges sur ce que SQL est et comment fonctionne son système de type, PostgreSQL est (heureusement) beaucoup moins indulgent. Vous devriez toujours développer et déployer sur la même pile et même s'applique jusqu'aux numéros de version.