【问题标题】:Python pyodbc connections to IBM Netezza ErroringPython pyodbc 连接到 IBM Netezza 错误
【发布时间】:2014-02-27 10:51:49
【问题描述】:

所以。这个问题与here 讨论的问题几乎完全相同——但是在那篇文章中讨论的修复(例如)并没有为我解决问题。

我正在尝试使用 Python 2.7.5 和 pyodbc 3.0.7 从 Ubuntu 12.04 64 位机器连接到 IBM Netezza 数据库。我正在使用 unixODBC 来处理指定 DSN。这个 DSN 在isql CLI 中运行良好——所以我知道它配置正确,并且 unixODBC 正在运行。

代码目前非常简单,并且很容易在 REPL 中重现:

In [1]: import pyodbc
In [2]: conn = pyodbc.connect(dsn='NZSQL')
In [3]: curs = conn.cursor()
In [4]: curs.execute("SELECT * FROM DB..FOO ORDER BY created_on DESC LIMIT 10")
Out[4]: <pyodbc.Cursor at 0x1a70ab0>

In [5]: curs.fetchall()
---------------------------------------------------------------------------
InvalidOperation                          Traceback (most recent call last)
<ipython-input-5-ad813e4432e9> in <module>()
----> 1 curs.fetchall()

/usr/lib/python2.7/decimal.pyc in __new__(cls, value, context)
    546                     context = getcontext()
    547                 return context._raise_error(ConversionSyntax,
--> 548                                 "Invalid literal for Decimal: %r" % value)
    549
    550             if m.group('sign') == "-":

/usr/lib/python2.7/decimal.pyc in _raise_error(self, condition, explanation, *args)
   3864         # Errors should only be risked on copies of the context
   3865         # self._ignored_flags = []
-> 3866         raise error(explanation)
   3867
   3868     def _ignore_all_flags(self):

InvalidOperation: Invalid literal for Decimal: u''

所以我得到一个连接,查询正确返回,然后当我尝试获取一行时...... asplode。

有人做过吗?

【问题讨论】:

    标签: python odbc pyodbc netezza


    【解决方案1】:

    原来pyodbc 不能优雅地转换所有 Netezza 的类型。我正在使用的表有两个有问题:

    • NUMERIC(7,2) 类型的列
    • NVARCHAR(255) 类型的列

    NUMERIC 列在 NULL 上导致十进制转换错误。 NVARCHAR 列返回一个 utf-16-le 编码的字符串,这很麻烦。

    我还没有找到一个好的驱动程序或包装程序级别的解决方案。这可以通过在 SQL 语句中强制转换类型来破解:

    SELECT
         foo::FLOAT AS was_numeric
         , bar::VARCHAR(255) AS was_nvarchar
    

    如果我找到较低级别的答案,我会在这里发布。

    【讨论】:

    • 您找到解决此问题的不同方法了吗?我刚遇到这个问题。
    • 不,恐怕我还没有。看来这是一个需要在pyodbc 本身中纠正的问题,而我手头没有那么多时间:-/
    • 我在 SQL 服务器 (bigint) 上遇到了同样的错误,并且我对坏列 (foo) 的投射看起来更像这样 select cast(foo as FLOAT) foo from table_name
    【解决方案2】:

    我刚刚遇到同样的问题并找到了不同的解决方案。 我设法通过以下方式解决了这个问题:

    1. 确保以下属性是我在 odbc ini 文件中的驱动程序选项的一部分:

      • UnicodeTranslationOption = utf16
      • CharacterTranslationOption = 全部
    2. 添加以下环境变量:

      • LD_LIBRARY_PATH=$LD_LIBRARY_PATH:[NETEZZA_LIB_FILES_PATH]
      • ODBCINI=[ODBC_INI_FULL_PATH]
      • NZ_ODBC_INI_PATH=[ODBC_INI_FOLDER_PATH]

      在我的例子中,这些值是:

      • LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/nz/lib
      • ODBC_INI=/etc/odbc.ini
      • NZ_ODBC_INI_PATH=/etc

    我使用的是 centos 6,还安装了 'unixODBC' 和 'unixODBC-devel' 软件包。

    希望它可以帮助某人。

    【讨论】:

    • 这两个是做什么的:UnicodeTranslationOption = utf16CharacterTranslationOption = all?
    • 谢谢,这很有用,但还有两件事:由于链接失效,此信息可能会丢失。此外,可能还有一个问题 - 除了 all 之外,第二个值的有效选项是什么?
    • 很遗憾我不知道。在我的情况下,这些是我必须设置的值,所以它会起作用。其他值不起作用。除了 all 之外,从未找到其他值。
    • @Koby 该链接似乎不再失效。找到这个ibm.com/support/knowledgecenter/SSZJPZ_8.7.0/…
    【解决方案3】:

    我不确定您的错误是什么,但下面的代码允许我通过 ODBC 连接到 Netezza:

    # Connect via pyodbc to listed data sources on machine
    import pyodbc
    print pyodbc.dataSources()
    
    print "Connecting via ODBC"
    
    # get a connection, if a connect cannot be made an exception will be raised here
    conn = pyodbc.connect("DRIVER={NetezzaSQL};SERVER=<myserver>;PORT=<myport>;DATABASE=<mydbschema>;UID=<user>;PWD=<password>;")
    
    print "Connected!\n"
    
    # you can then use conn cursor to perform queries
    

    【讨论】:

      【解决方案4】:

      Netezza Linux 客户端软件包包括/usr/local/nz/lib/ODBC_README,其中列出了这两个属性的所有值:

      UnicodeTranslationOption:
          为 Unicode 指定翻译选项。
          可能的值字符串是:
              utf8 : unicode 数据采用 utf-8 编码
              utf16 : unicode 数据采用 utf-16 编码
              utf32 : unicode 数据采用 utf-32 编码
          不要在上面列出的值字符串中添加“-”,例如“utf-8”不是
          一个有效的字符串值。这些值字符串不区分大小写。
      
          在 Windows 上,此选项不可用,因为 Windows DM 总是通过
          utf16 中的 unicode 数据。
      
      CharacterTranslationOption(Windows 上的“针对 ASCII 字符集进行优化”):
          指定字符编码的翻译选项。
          可能的值字符串是:
              all : 支持所有字符编码
              latin9 :仅支持 Latin9 字符编码
          不要在上面列出的值字符串中添加“-”,例如“拉丁-9”
          不是有效的字符串值。这些值字符串是大小写
          不敏感。
      
          NPS 对 char 和 varchar 使用 Latin9 字符编码
          数据类型。许多 Windows 系统上的字符编码
          与此相似,但不完全相同。对于 ASCII 子集
          (字母 a-z、A-Z、数字 0-9 和标点符号)它们是
          完全相同的。如果 CHAR 或 VARCHAR 数据类型中的字符数据是
          仅在此 ASCII 子集中,如果此框为
          检查。如果您的数据包含特殊字符,例如欧元
          签名 (€) 然后保持该框未选中以准确转换
          编码。 NCHAR 或 NVARCHAR 数据类型中的字符
          将始终适当地转换。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-13
        • 1970-01-01
        • 2022-09-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多