2

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

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)

データが 4000 バイトを超える CLOB 列を持つテーブルに挿入しようとすると、「ValueError: string data too large」というメッセージが表示されます。Executemany は、テーブルに CLOB 列がない場合にうまく機能します。executemany を実行するときに、適切な列を CLOB として扱うように cx_Oracle に指示する方法はありますか?

4

1 に答える 1

4

大きな列の入力サイズを に設定してみてくださいcx_Oracle.CLOB。バイナリ データがある場合は機能しない可能性がありますが、CSV. この2K値は、必要以上に低い可能性があります。

executemany関係する列がある場合はかなり遅くなるように見えますがCLOB、繰り返し実行するよりはまだ良いことに注意してください。

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)
于 2012-08-28T05:36:48.237 に答える