3

データを別のアプリケーションに正しくロードできるように、列の型情報を保持しながら、さまざまなデータベース (現時点では Oracle と Postgre) からいくつかのデータを CSV ファイルにダンプする必要があります。基本的に、使用中の特定の DBAPI モジュールに依存しない方法で、列データ内の文字列/数値データをカーソル オブジェクトから区別できる関数を作成する必要があります。

DB-API v2 docsによると、各 DBAPI モジュールは、各列 ( n 番目の列など)module.STRINGのカーソル オブジェクト内の型オブジェクトと「等しい必要がある」型オブジェクト (たとえば )を定義する必要があります。cursor.description[n][1]

私が抱えている問題は...カーソルオブジェクトにしかアクセスできない場合、この比較に適切なタイプオブジェクトをどのように把握できますか? カーソル オブジェクトから適切な DBAPI モジュールへのハンドルを取得するにはどうすればよいですか。アドバイスや提案はありますか?

私はこれまで醜いクラッジを使用してきました:

def FigureOutDBTypes(cursor):
    if 'psycopg2' in str(type(cursor)):
        coltypes = [(str if x[1]==1043 else int) for x in cursor.description] 
    elif 'Oracle' in str(type(cursor)):
        typemap = dict(NUMBER = int,
                       DATE = int,
                       DATETIME = int,
                       TIMESTAMP = int,
                       STRING = str)
        coltypes = [typemap.get(x[1] and x[1].__name__, int) for x in cursor.description]
    else:
        raise RuntimeError("Don't know how to get type information from DB cursor.", cursor)
    return coltypes

これに対するより堅牢でエレガントなソリューションが必要です。アドバイスや提案はありますか?

編集:これまでに私が思いついた最善のことは、次のほとんど恐ろしいハックを使用して適切なモジュールへのハンドルを取得することです:

mod = sys.modules[cur.connection.__class__.__module__] #FIXME!
coltypes = [(str if x[1]==mod.STRING else int) for x in cursor.description]
4

0 に答える 0