2009-12-06 9 views
2

Environnement:
Rails 2.3.2
DBI 0.4.1
DBD/ODBC 0.2.4config.cache_classes = true affectant la contrainte de type avec RubyDBI

Scénario:
J'ai une application Rails que les importations la plupart de ses données proviennent de bases de données SQL externes dans la base de données SQL Rails via des tâches par lots régulières. Ces tâches par lots commencent par charger l'environnement Rails, puis procèdent à des connexions directes à la base de données via RubyDBI. Une fois connecté, j'exécute des instructions select pour extraire les données, les masser et créer des objets ActiveRecord.

Je viens sur une question étrange où le comportement est différent dans le développement puis dans la production. Il semble que lorsque config.cache_classes est vrai, DBI arrête correctement le type exerce des pressions sur SQL DATETIME retourné dans un datetime Ruby. Voici un exemple de code extrait:

## config.cache_classes = true 
query = "select TOP 1 [EPOLeafNode].[Lastupdate] AS last_update from [EPOLeafNode]" 
conn = DBI.connect('dbi:ODBC:DRIVER=FreeTDS;TDS_Version=8.0;SERVER=sql;DATABASE=EOP;uid=uid;pwd=pwd;') 
conn.select_one(query) 
=> ["2008-11-05 20:53:26.000"] 

## config.cache_classes = false 
query = "select TOP 1 [EPOLeafNode].[Lastupdate] AS last_update from [EPOLeafNode]" 
conn = DBI.connect('dbi:ODBC:DRIVER=FreeTDS;TDS_Version=8.0;SERVER=sql;DATABASE=EOP;uid=uid;pwd=pwd;') 
conn.select_one(query) 
=> [[Wed, 05 Nov 2008 20:53:26 +0000]] 

Est-ce un bug ou le comportement attendu que je ne comprends pas? Puis-je le remplacer, de préférence pour toujours contraindre les données? Si non, des réflexions sur la meilleure façon de masser les données afin qu'il donne le même résultat dans le développement et la production?

+0

Le code extrait est-il typo? Le premier 'select_one' semble retourner un tableau avec un seul élément de chaîne, et le second un tableau avec un seul élément de tableau contenant un seul objet DateTime. – pilcrow

+0

je certainement ai typo'd quelque chose, mais notez que l'objet englobante est pas un tableau, il est un DBI :: Row. IRB le met en forme entre crochets et vous pouvez appeler [0] pour obtenir le résultat. En ce qui concerne les supports internes, je ne suis pas sûr ... –

Répondre

0

Non, ce comportement est une interaction attendue.

Pour contourner ce problème rapide et sale, vous pouvez explicitement CAST le champ lastupdate dans une chaîne, qui devrait fonctionner dans les deux environments.rb.

Conversion à un type numérique simple, comme un horodatage UNIX, pourrait fonctionner aussi.

Je ne peux pas dire ce que la racine du problème est, et je ne peux pas reproduire les mêmes versions de Rails/AR et DBI, il est vrai avec une base différente. Cependant, il y a un peu de dynamisme dans les deux paquets, et le chargement ou la modification partielle d'une classe de support peut ne pas faire ce que DBI attend. (Il y a quelque temps, par exemple, l'adaptateur AR de l'ancien singe de pilote postgres a corrigé le pilote de base, le brisant pour les anciennes versions du DBD associé.)

Questions connexes