pandas - 对read_sql_query()的cdecimal.ConversionSyntax invalidOperation

时间:2015-09-29 14:53:58

标签: python pandas

在处理数据库decimal数据类型时,我遇到了Pandas read_sql_query()函数的问题。使用varcharinteger类型时,我对以下相同代码没有任何问题。

版本信息:

CentOS 6.6
Python 2.7.10 :: Anaconda 2.3.0 (64-bit)
# packages in environment at /opt/anaconda:
pandas                    0.16.2               np19py27_0
cdecimal                  2.3                      py27_0
pyodbc                    3.0.10                   py27_0
sqlalchemy                1.0.8                    py27_0

下面是我的代码尽可能减少复制错误。我也试过通过sqlalchemy并得到了同样的错误。 (netezza没有sqlalchemy引擎所以它仍然需要依赖pyodbc。)

import pyodbc 
import pandas as pd 
connection = pyodbc.connect("Driver={NetezzaSQL};servername=nzserver;database=MASTER;username=USER_GUY;password=****")

sql = "select cast(0.0 as decimal(6,2)) as testing "

data = pd.io.sql.read_sql_query(sql, connection, index_col=None, coerce_float=True)

#Also tried this, same error   
data = pd.io.sql.read_sql_query(sql, connection, index_col=None, coerce_float=False)


---------------------------------------------------------------------------
InvalidOperation                          Traceback (most recent call last)
<ipython-input-217-ba167303e6b2> in <module>()
      1 
----> 2 data = pd.io.sql.read_sql_query(sql, connection, index_col=None, coerce_float=True)
      3 # InvalidOperation: [<class 'cdecimal.ConversionSyntax'>]
      4 

2 个答案:

答案 0 :(得分:2)

看起来这是一个已知的issue pyodbc。那里有一个你可能会尝试的补丁。 netezza甚至还有一个评论。

答案 1 :(得分:0)

好的,所以我让Pandas read_sql_query()使用Netezza decimal数据类型。我是通过从pyodbc切换到pypyodbc(描述为here)来完成此操作的。

我注意到结果中有unicode的一些奇怪的东西,所以我将一些额外的参数传递给pypyodbc中的连接对象,现在事情似乎正常了。我需要更改unicode_results=Falseansi=true(对于数据库输出/消息)...但我认为我没关系,因为我的数据应该适合ASCII并且我甚至不确定如何新西兰无论如何都支持unicode。

下面的工作代码可以从查询中获取data.frame

import pypyodbc
import pandas as pd
connection = \
pypyodbc.connect(
    "Driver=NetezzaSQL;SERVERNAME=nzserver;DATABASE=MASTER;PORT=5480;USERNAME=user_guy;PASSWORD=******",
    ansi=True,
    unicode_results=False)

sql = """select 
            cast(0.0 as decimal(6,2))      as decimal_test, 
            cast(0 as integer)             as int_test, 
            cast('aosenuth' as varchar(5)) as varchar_test ,
            current_timestamp              as timestamp_test """
data = pd.io.sql.read_sql_query(sql, connection, index_col=None, coerce_float=True)

print data.shape