2012-09-24 12 views
9

Sto convertendo un'app per rails dall'utilizzo di mysql (mysql2 gem) a postgres (pg gem).connection.select_value restituisce solo stringhe in postgres con pg gem

con MySQL, ActiveRecord::Base.connection.select_value chiamate valori tipizzati in base ai dati di ritorno, per esempio:

> ActiveRecord::Base.connection.select_value("SELECT COUNT(*) FROM errors") 
=> 86 
> ActiveRecord::Base.connection.select_value("SELECT exception FROM errors where id=565") 
=> "TechTalk.Genome.SqlExecutionException" 
> ActiveRecord::Base.connection.select_value("SELECT id FROM errors where id=565") 
=> 565 

Tuttavia, con Postgres, connection.select_value restituisce sempre una stringa:

> ActiveRecord::Base.connection.select_value("SELECT COUNT(*) FROM errors") 
=> "1" 
> ActiveRecord::Base.connection.select_value("SELECT id FROM errors") 
=> "1" 
> ActiveRecord::Base.connection.select_value("SELECT source FROM errors limit 1") 
=> "webapp" 

Questo ha rotto un paio di unità test, e mentre quelli sono risolvibili, sono certo che abbiamo altri codici che si basano su questi valori di ritorno. C'è un modo per ottenere valori di ritorno tipizzati correttamente da connection.select_value quando si utilizza postgres?

risposta

4

La risposta breve è no. Il driver 'pg' fornisce intenzionalmente un layer il più sottile possibile sopra il driver nativo 'libpq'. Non esegue il typecasting, poiché è responsabilità delle librerie di livello superiore che hanno alcune informazioni sul dominio in cui verranno utilizzati i risultati. Il fondamento logico di questa decisione è documentato on the PostgreSQL Wiki e sarei felice di discuterlo con voi ulteriormente on the mailing list.

+4

La peggiore risposta migliore di sempre! ;) Grazie. –

+0

"sottile un livello il più possibile sopra il driver nativo" libpq "." il problema è che le allocazioni di stringhe in ruby ​​sono in realtà piuttosto costose, sembra così dispendiosa –

+0

Penso che sia una questione di circostanza se sia più dispendioso allocare stringhe per ogni colonna o provare a mappare i tipi PostgreSQL in Ruby per impostazione predefinita. Se i tuoi tipi di colonna hanno tutti gli equivalenti derivati ​​numerici (non BigNum) in Ruby, probabilmente è inutile rappresentarli tutti come stringhe. Tuttavia, mi sembra irresponsabile implementare quello che può essere solo un sistema di mappatura dei tipi parzialmente completo basato sul potenziale spreco di memoria in quella circostanza relativamente rara. –

0

Per coloro che sbarcano qui in cerca di un ActiveRecord attributi (rotaie) risposta specifica: che ho fatto alcuni test (https://gist.github.com/gamov/8fe38733012931eb3360) e ha scoperto che:

RequestedItem.where(id: 1).select(*, 10 AS tq).first.tq.class 

restituisce una stringa con Rails < 4 e un Fixnum with Rails> = 4.

L'adattatore Postgres inoltra i tipi dal DB al modulo Persistenza in modo che la trasmissione possa essere eseguita in modo trasparente.

Problemi correlati