LoginSignup
1
0

More than 5 years have passed since last update.

cx_OracleでOracleのXMLTYPEを操作する

Posted at

cx_OracleでOracleのXMLTYPEを操作する

環境

  • python:3.7.1
  • cx_Oracle:7.0.0

XMLデータ

今回利用するXMLは郵便番号のデータとしました。
日本郵便のサイトからダウンロードできるデータはcsvのみでしたので、
http://blog.majide.com/2009/03/jp-post-zipcode-xml/
のサイトのデータを利用しました。

<JapanAreaData>
  <Prefecture>
    <City>
      <Area>
        <AreaKana>コウキョガイエン</AreaKana>
        <AreaName>皇居外苑</AreaName>
        <ZipCode>1000002</ZipCode>
      </Area>
      <Area>
      ・・・
      </Area>
      <CityName>千代田区</CityName>
      <CityNameKana>チヨダク</CityNameKana>
    </City>
    <City>
    ・・・
    </City>
    <PrefectureKana>トウキョウト</PrefectureKana>
    <PrefectureName>東京都</PrefectureName>
  </Prefecture>
</JapanAreaData>

OracleのXMLTYPEについて

XMLTYPEはその名の通り、XMLデータを保持する型となります。
XMLのみを保持するCLOB型と考えればわかりやすいでしょうか。
また、XPath式を使用してXMLデータを操作できるため、XMLと非常に相性の良いという特徴を持ちます。

cx_OracleでのXMLTYPEについて

今回扱うデータはXMLと非常にサイズが大きいため、Insertする際はバインド変数を使用する必要があります。
cx_Oracleでバインド変数を使用する際は、カーソルのCursor.setinputsizesでサイズを指定(拡張)する必要があります。
これを指定しない場合、「cx_Oracle.DatabaseError: ORA-01461: LONG値はLONG列にのみバインドできます。」が発生します。
今回はXMLTYPEですので、サイズはcx_Oracle.CLOBを指定します。

cur.setinputsizes(<バインド変数の変数名>=cx_Oracle.CLOB)

ソース

import cx_Oracle

if __name__ == '__main__':

    zip_xml = ""
    # 郵便番号のxmlファイル
    with open('/path/to/jp_zipcode.xml', 'r', encoding='utf-8') as f:
        for s_line in f:
            zip_xml += s_line

    # Oracle接続
    conn = cx_Oracle.connect("test_user", "P@ssW0rd", "localhost:1521/xe")
    cur = conn.cursor()

    # XMLTYPEをバインドするため、cx_Oracle.CLOBを指定する
    cur.setinputsizes(zip=cx_Oracle.CLOB)
    param = {'zip': zip_xml}
    cur.prepare("insert into zip_xml values(xmltype(:zip))")
    cur.execute(None, param)
    conn.commit()
    cur.execute("select extract(zip, '/JapanAreaData/Prefecture/City/Area[ZipCode=1000002]').getClobVal() from zip_xml")
    res = cur.fetchone()
    print("郵便番号「1000002」のデータ確認")
    print(res[0])
    conn.close()

実行結果

$ python test_xmltype.py 
郵便番号「1000002」のデータ確認
<Area>
  <AreaKana>コウキョガイエン</AreaKana>
  <AreaName>皇居外苑</AreaName>
  <ZipCode>1000002</ZipCode>
</Area>

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0