2011-07-08 13 views
2

複数のCSVを解析し、cx_Oracleを使用してそのデータをテーブルに挿入しようとしています。実行時にテーブルに挿入するのに問題はありませんが、executemanyで同じ手順を試すとエラーが発生します。動作する実行使用して私のコードはCLXを持つcx_Oracle executemany

with open(key,'r') as file: 
    for line in file: 
     data = data.split(",") 
     query = "INSERT INTO " + tables[key] + " VALUES (" 
     for col in range(len(data)): 
      query += ":" + str(col) + "," 
     query = query[:-1] + ")"    
     cursor.execute(query, data) 

ですが、私は

with open(key,'r') as file: 
    list = [] 
    for line in file: 
     data = data.split(",") 
     list.append(data) 
    if len(list) > 0: 
     query = "INSERT INTO " + tables[key] + " VALUES (" 
     for col in range(len(data)): 
      query += ":" + str(col) + "," 
     query = query[:-1] + ")"    
     cursor.prepare(query) 
     cursor.executemany(None,list) 

と交換したとき、私は「とValueError:文字列データが大きすぎる」を取得するCLOB列があると、テーブルに挿入しようとしたときデータは4000バイト以上です。 Executemanyは、表にCLOB列がない場合に有効です。 executemanyを実行するときに、適切な列をCLOBとして扱うようにcx_Oracleに指示する方法はありますか?

答えて

3

大きな列の入力サイズをcx_Oracle.CLOBに設定してみてください。バイナリデータを持っていればうまくいかないかもしれませんが、あなたが持っているテキストはCSVで動くはずです。 2Kの値は、必要な値より低い可能性があります。

def _executemany(cursor, sql, data): 
    ''' 
    run the parameterized sql with the given dataset using cursor.executemany 
    if any column contains string values longer than 2k, use CLOBS to avoid "string 
    too large" errors. 

    @param sql parameterized sql, with parameters named according to the field names in data 
    @param data array of dicts, one per row to execute. each dict must have fields corresponding 
       to the parameter names in sql 
    ''' 
    input_sizes = {} 
    for row in data: 
     for k, v in row.items(): 
      if isinstance(v, basestring) and len(v) > 2000: 
       input_sizes[k] = cx_Oracle.CLOB 
    cursor.setinputsizes(**input_sizes) 
    cursor.executemany(sql, data) 
executemanyが多く関与 CLOB列があるとき遅くなりますが、繰り返し実行よりもまだ良いと思われること

注意

関連する問題