【Python3】Oracle Database에의 접속과 SQL 실행 【cx_Oracle】

소개



Python3에서 cx_Oracle 패키지를 사용하는 방법을 요약했습니다.
이것만 있으면 어느 정도의 개발은 할 수 있다고 생각합니다.

중요한 일이므로 처음에 말해 둡니다만, 공식 문서를 보는 것이 제일 정확해요.
cx_Oracle 공식 문서

시스템 구성


  • 클라이언트 PC
  • Windows10 Pro 64bit
  • Windows PowerShell
  • Python 3.8.0
  • pip 19.2.3
  • cx_Oracle 7.2.3

  • 데이터베이스
  • Oracle Database 12c Release 1


  • 패키지 설치



    PowerShell
    pip install cx_Oracle
    

    오류 발생 시
    Windows에는 표준으로 C 컴파일러가 부속되어 있지 않기 때문에, pip로의 인스톨시에 아래와 같은 메세지를 포함한 에러가 발생하는 경우가 있다.

    error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": h tps:///ゔぃすあ lsつぢ오. mic로소 ft. 코 m/두w응아 ds/

    그 경우는 Visual Studio의 다운로드 페이지에 있는 「Build Tools for Visual Studio 2019」를 인스톨 할 필요가 있다. (2019/11/23 현재)

    [최소한 필수 구성]
    워크로드
    · C++ Build Tools
    옵션
    · MSVC v142 - VS 2019 C++ x64/x86 빌드 도구
    · Windows 10 SDK

    데이터베이스에 연결



    connect.py
    # パッケージのインポート
    import cx_Oracle
    
    HOST = "localhost"
    PORT = 1521
    SVC_NM = "hoge.example.com"
    
    # 接続記述子の生成
    dsn = cx_Oracle.makedsn(HOST, PORT, service_name = SVC_NM)
    
    # コネクションの確立
    connection = cx_Oracle.connect(USER, PASS, dsn, encoding = "UTF-8")
    
    # SQL発行などの処理...
    
    # コネクションの解放
    connection.close()
    

    패키지 가져오기


    import cx_Oracle
    

    연결 설명자 생성


    HOST = "localhost"
    PORT = 1521
    
    # SID(インスタンス識別子)を使用する場合
    SID = "hoge"
    dsn = cx_Oracle.makedsn(HOST, PORT, sid = SID)
    
    # SERVICE_NAME(サービス名)を使用する場合
    SVC_NM = "hoge.example.com"
    dsn = cx_Oracle.makedsn(HOST, PORT, service_name = SVC_NM)
    
    # NET_SERVICE_NAME(ネットサービス名、接続識別子)を使用する場合
    NET_SN = "hogenet"
    dsn = cx_Oracle.makedsn(HOST, PORT, NET_SN)
    
    # 生成された接続記述子(例: SERVICE_NAME)
    print(dsn)
    # >> (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=hoge.example.com)))
    

    cx_Oracle.makedsn()
    인수로 건네준 파라미터에 근거해 접속 식별자를 돌려줍니다.

    ※넷 서비스명(접속 식별자)을 사용하는 경우
    미리 클라이언트 측에서 tnsnames.ora를 구성해야 합니다.

    커넥션의 확립과 해방


    # コネクションの確立
    connection = cx_Oracle.connect(USER, PASS, dsn, encoding = "UTF-8")
    
    # SQL発行などの処理...
    
    # コネクションの解放
    connection.close()
    

    with 구문을 사용하여 with 블록을 벗어나면 자동으로 연결을 해제할 수 있습니다.
    특별한 이유가 없으면, 개인적으로는 ↓이쪽이 좋다고 생각합니다.
    with cx_Oracle.connect(USER, PASS, dsn, encoding = "UTF-8") as connection:
        # SQL発行などの処理...
        # connection.close()の記述は不要
    

    SQL 실행



    query.py
    # カーソル生成
    cursor = connection.cursor()
    
    # バインド変数
    sql = "select * from countries where country_id = :id"
    bind_data = { id: 1 }
    
    # SQL発行
    cursor.execute(sql, bind_data)
    
    # データ取得
    rows = cursor.fetchall()
    
    # バインドする値の変更
    bind_data["id"] = 2
    
    # SQL発行(ソフトパース)
    cursor.execute(sql, bind_data)
    
    # カーソル解放
    cursor.close()
    

    커서 생성 및 해제


    # カーソル生成
    cursor = connection.cursor()
    
    # カーソル解放
    cursor.close()
    

    연결과 마찬가지로 with 구문으로 자동으로 해제할 수 있습니다.
    특히 이유가 없으면 ↓ 여기를 추천합니다.
    with connection.cursor() as cursor:
        # SQL発行など...
        # cursor.close()の記述は不要
    

    바인드 변수


    # バインド変数(プレースホルダ)
    sql = "select country_id, country_name from countries where country_id = :id"
    
    # バインドする値の定義
    # 辞書型の場合
    bind_data = { id: 1 }
    
    # リスト型の場合
    bind_data = [1]
    


    사전형
    목록 유형


    바인드 변수와 key가 일치하는 값이 할당된다
    SQL 시작 부분에서 바인드 변수의 정렬 순서에 값이 할당됨


    SQL 발행


    cursor.execute(sql, bind_data)
    
    # キーワード引数も可
    cursor.execute(sql, id = 1)
    
    # バインド変数の値を変えてSQL再発行
    bind_data["id"] = 2
    cursor.execute(sql, bind_data)
    
  • SQL 문장에 세미콜론 (;)은 불필요
  • SELECT 문뿐만 아니라 INSERT 문, UPDATE 문 등도 발행 가능합니다.
  • 바인드 변수의 값을 변경하여 SQL을 다시 발행 할 수 있습니다.

    SOFT PARSE (소프트 퍼스)
    발행 된 SQL은 파서에 의해 해석되어 공유 풀에 캐쉬된다 (HARD PARSE (하드 퍼스)).
    소프트 퍼스에서는, 공유 풀에 캐쉬 된 해석 결과를 재사용하는 것에 의해, 퍼포먼스의 향상을 기대할 수 있다.

    데이터 획득


    # カーソルから一レコードずつ取得
    row = cursor.fetchone()
    print(row)
    # >> (1, Japan)
    
    # カーソルから任意のレコード数を取得(例: 10レコード)
    numRows = 10
    rows = cursor.fetchmany(numRows)
    print(rows)
    # >> [(1, Japan)]
    
    # カーソルから全てのレコードを取得
    rows = cursor.fetchall()
    print(rows)
    # >> [(1, Japan)]
    
  • 데이터는 커서에서 튜플로 가져옵니다
  • 여러 레코드를 얻은 경우 튜플 목록으로 가져옵니다

  • 거래



    transaction.py
    # 明示的なトランザクションの開始
    connection.begin()
    
    # SQL発行
    cursor.execute(
        "insert into countries (country_id, country_name) values (:id, :name))",
        id = 2, name = "United States"
    )
    
    # コミット
    connection.commit()
    
    # ロールバック
    connection.rollback()
    

    명시적 트랜잭션 시작


    # 省略可能
    connection.begin()
    

    Oracle Database는 첫 번째 SQL이 실행될 때 자동으로 트랜잭션을 시작하므로 특별한 이유가 없으면 명시 적으로 트랜잭션을 시작할 필요가 없습니다.

    커밋과 롤백


    # コミット
    connection.commit()
    
    # ロールバック
    connection.rollback()
    

    커밋하지 않고 데이터베이스 연결이 닫히면 트랜잭션이 롤백됩니다.
    ※connection.autocommit를 활성화한 경우를 제외

    Python3의 개발 환경 구축에 대해서는 이쪽!
    【Python3】개발 환경 구축《Windows편》

    Python3의 치트 시트도 있습니다!
    【Python3】다국어 엔지니어를 위한 Python 치트 시트《기초편》
    【Python3】다국어 엔지니어를 위한 Python 치트 시트《오브젝트 지향편》

    좋은 웹페이지 즐겨찾기