间歇" ORA-01458:变量字符串内的长度无效"使用SQLAlchemy将数据插入Oracle DB时出错

时间:2016-09-17 01:59:50

标签: python oracle oracle11g sqlalchemy cx-oracle

我正在开发一个Python 3.5服务器项目,并使用SQLAlchemy 1.0.12和cx_Oracle 5.2.1将数据插入到Oracle 11g中。我注意到我的许多多行表插入都是间歇性失败的" ORA-01458:变量字符串中的长度无效"错误。

我通常一次插入几千到几万行,数据主要由字符串,Pandas时间戳和浮点数组成。我做了以下观察:

  1. 在Python服务器的Windows和Linux主机操作系统上发生错误
  2. 错误总是间歇性地发生,即使数据没有改变
  3. 如果我不插入浮点数,或者如果我绕过它们,则错误发生的次数会减少但仍会发生
  4. 如果我一次插入一行,我就不会遇到错误(但这对我而言是不可接受的)
  5. 此外,如果遇到错误,我已尝试再次插入。我尝试的第一件事是将一个try-except块放在我在 sqlalchemy.engine.base.Connection 对象上调用execute的地方,如下所示:

    def do_executemany(self, cursor, statement, parameters, context=None):
        if isinstance(parameters, tuple):
            parameters = list(parameters)
    
        # original code
        # cursor.executemany(statement, parameters)
    
        # new code
        try:
            cursor.executemany(statement, parameters)
        except Exception as e:
            print('trying again')
            cursor.executemany(statement, parameters)
    

    我注意到使用这种方法,第二次插入仍然经常失败。我尝试的第二件事是在sqlalchemy包(sqlalchemy \ dialects \ oracle \ cx_oracle.py)中 OracleDialect_cx_oracle do_executemany 的实现中尝试相同:

    {{1}}

    奇怪的是,当我这样做时,第二个 executemany 调用将始终有效,如果第一个失败。我不确定这意味着什么,但我相信这指向cx_Oracle驱动程序是问题的原因而不是sqlalchemy。

    我在网上到处搜索,没有看到任何相同问题的报道。任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:0)

我们发现,如果在插入之前将所有float.nan对象替换为None,则错误将完全消失。非常奇怪!

答案 1 :(得分:0)

我有同样的问题,代码有时会失败,有时会没有错误。显然我的块大小对于缓冲区来说很大,一旦我将块大小从10K减少到500行,就不再出现错误。