2012-09-24 12 views
9

Estoy convirtiendo una aplicación de rieles de usar mysql (gema mysql2) a postgres (gema pg).connection.select_value solo devuelve cadenas en postgres con la gema de pg

con MySQL, ActiveRecord::Base.connection.select_value llamadas valores escritos de acuerdo con los datos de retorno, por ejemplo:

> 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 

Sin embargo, con postgres, connection.select_value siempre devuelve una cadena:

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

Esto rompió unos cuantos unidad pruebas, y si bien estas son corregibles, estoy seguro de que tenemos otro código que depende de estos valores de retorno. ¿Hay alguna forma de obtener los valores devueltos correctamente tipados desde connection.select_value al usar postgres?

Respuesta

4

La respuesta corta es no. El controlador 'pg' proporciona intencionalmente la capa más fina posible sobre el controlador nativo 'libpq'. No es un tipo de conversión, ya que es responsabilidad de las bibliotecas de nivel superior que tengan una idea del dominio en el que se utilizarán los resultados. La razón de esta decisión está documentada en on the PostgreSQL Wiki, y con gusto la discutiré con usted más adelante on the mailing list.

+4

¡La peor respuesta posible! ;) Gracias. –

+0

"adelgace una capa lo más posible sobre el controlador nativo 'libpq'". El problema es que las asignaciones de cadenas en ruby ​​son realmente bastante caras, parece ser un desperdicio. –

+0

Creo que es una cuestión de circunstancias si es más inútil asignar cadenas para cada columna o intentar asignar tipos de PostgreSQL a Ruby de forma predeterminada. Si todos los tipos de columna tienen equivalentes numéricos exactos (no BigNum) en Ruby, probablemente sea un desperdicio representarlos a todos como cadenas. Sin embargo, me parece irresponsable implementar lo que solo puede ser un sistema de mapeo de tipos parcialmente completo basado en el posible desperdicio de memoria en esa circunstancia comparativamente rara. –

0

Para los que la tierra aquí en busca de un ActiveRecord atributos (rieles) respuesta específica: que he hecho algunas pruebas (https://gist.github.com/gamov/8fe38733012931eb3360) y descubrió que:

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

devuelve una cadena con los carriles 4 y un < Fixnum con Rails> = 4.

El adaptador Postgres reenviará los tipos de la base de datos al módulo de persistencia para que la conversión se pueda realizar de forma transparente.

Cuestiones relacionadas