Python3 Cx_oracleのいくつかのテクニック


Cx_oracleのいくつかのテクニック
JAN 16TH, 2012
作業中のデータベースはoracleを採用しています.Oracleデータベースへのアクセスには、一般的にcx_が使用されます.oracleパッケージが完成し、APIがはっきりしていて、操作効率も高いし、oracle公式はcx_oracleも非常にサポートされており、豊富なドキュメントを提供しています.ここでは、記録として使用するテクニックについて議論します.あなたにも役に立つかもしれません.
私は最近pythonで、クライアントの要求に基づいてデータベースを問合せ、結果セットをjsonで返す小さなツールを書きました.要求のフォーマットは次のとおりです.
   1: {
   2:     fields : [
   3:         {name : "project_id", type : "string"},
   4:         {name : "project_name", type : "string"}
   5:     ],
   6:     
   7:     sql : "select t.project_id, t.project_name from dp_project t"
   8: }

すなわち、クライアントは、自分が望むメタデータ情報(フィールド名、フィールドタイプ)を記述し、SQL文を記述し、サーバ側はこの情報に基づいてデータベースを問合せ、クライアントがfieldsで記述したように組織します.
cx_oracleのデフォルトでcursorからfetchされたデータは、SQLの順序で整理されたメタグループですが、cursorのrowfactoryプロパティを設定することで実現できる辞書構造を返します.rowfactoryのコールバック関数を定義します.
   1: def makedict(self, cursor):
   2:     cols = [d[0] for d in cursor.description]
   3:  
   4:     def createrow(*args):
   5:         return dict(zip(cols, args))
   6:  
   7:     return createrow

この関数は、createrowという関数を返します.ちょっと早口かもしれませんが、よく考えてみるとはっきりしています.cursorには、cursorのdescriptionの値が次のような辞書を生成するのに十分な情報があります.
   1: [
   2: ('PROJECT_ID', <;type 'cx_Oracle.STRING'>, 40, 40, 0, 0, 0), 
   3: ('PROJECT_NAME', <;type 'cx_Oracle.STRING'>, 50, 50, 0, 0, 1)
   4: ]

必要なのはcursorですdescriptionの最初の列では、zip関数はcolsとデフォルトのメタを組み合わせて新しいメタグループにし、dictで新しい辞書オブジェクトに変換して返します.
次に、この関数を返す関数をcursorのrowfactoryに登録します.
   1: cursor.rowfactory = self.makedict(cursor)

これでcursorを使います.fetchall/fetchoneの場合、取り出したものは辞書のオブジェクトとなり、json形式にシーケンス化して返すのが便利です.
もう1つのテクニックは、クエリの結果を文字列タイプのフィールドをunicodeに変換し、数値タイプを処理しないことです.
   1: def outtypehandler(self, cursor, name, dtype, size, p, s):
   2:     if dtype in (oracle.STRING, oracle.FIXED_CHAR):
   3:         return cursor.var(unicode, size, cursor.arraysize)

この関数にconnectionオブジェクトのoutputtypehandlerを登録します.
   1: connection = oracle.connect(self.constr)
   2: connection.outputtypehandler = self.outtypehandler

汎用クエリーのこのガジェットはまだ開発中で、完成してから整理します.
Posted by Qiu Juntao Jan 16th, 2012  python
オリジナルリンク、著作権声明:自由転載-非商用-非派生-署名保持|Creative Commons BY-NC-ND 3.0