Database JUNKY

MySQL,MariaDBを中心としたブログです

python3から、MySQLのストアドプロシージャをCALLする

python3でコードを書いているうちに、MySQLに関わる部分のソースが煩雑になってしまうため、ビジネスロジックは、全て、MySQLのストアドプロシージャにまかせるってことでこんなに綺麗なソースじなります。(あくまでも個人的な主観ですが)

なお、python3でのMySQLライブラリは、MySQLdb を利用しています

f:id:hit10231023:20180302202040p:plain f:id:hit10231023:20180309104332j:plain

MySQLストアドプロシージャについて

ここでは、ストアドの内容の説明いついては割愛しますが、こんなコードを書いています。 まあ、単純には、videoidを元にレコードを3件書き込んでいる処理です。 エラーチェックとかは、別にしていないので、あくまでも例ってことでw

CREATE PROCEDURE `sp_put_copylist`(
IN _videoid bigint,
OUT _result int(11)
)
BEGIN

  SET _result = 0 ;
  
  BEGIN
    DECLARE _not_found tinyint UNSIGNED DEFAULT 0;
    
    DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
      SET _result = -99;
    END;

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET _not_found = 1;
    
    BEGIN
      INSERT INTO
         work_schema.copylist
      (
       TargetFile,
       OriginalFile,
       FileGroup,
       VideoId
      )
      SELECT
        filename || '.file.jpg'  AS TargetFile,
        filename || '.file.80s.jpg'  AS OriginalFile,
        140 AS FileGroup,
        Id AS VideoId
      FROM
        schema.videos
      WHERE
        id = _videoid ;

      INSERT INTO
         work_schema.copylist
      (
       TargetFile,
       OriginalFile,
       FileGroup,
       VideoId
      )
      SELECT
        filename || '.file.small.jpg'  AS TargetFile,
        filename || '.file.80s.small.jpg'  AS OriginalFile,
        140 AS FileGroup,
        Id AS VideoId
      FROM
        schema.videos
      WHERE
        id = _videoid ;

      INSERT INTO
         work_schema.copylist
      (
       TargetFile,
       OriginalFile,
       FileGroup,
       VideoId
      )
      SELECT
        filename || '.file.tiny.jpg'  AS TargetFile,
        filename || '.file.80s.tiny.jpg'  AS OriginalFile,
        140 AS FileGroup,
        Id AS VideoId
      FROM
        schema.videos
      WHERE
        id = _videoid ;          

      SET _result = 0 ;


    END ;
  END;
END $$

DELIMITER ;

python3でのコード

上記ストアドプロシージャを、python3上でCALLする例です(一部抜粋) エラーチェックとかは、別にしていないので、あくまでも例ってことでw

import MySQLdb
・
・
・
    # _videoidsを改行で分割
    _videolist = _videoids.split()

    # MySQL connect
    cn = getConnection()
    c = cn.cursor(MySQLdb.cursors.DictCursor)

    for v in _videolist:
       _videoid = v.strip()
       try:

          if _videoid == '':
             print("skip")
             break

          args = (_videoid, 0)
          result_args = c.callproc('work_schema.sp_put_copylist', args)
          print(result_args)


       except MySQLdb.Error as e:
           print("MySQLdb.Error: ",e)

       # finally:
       #    cn.commit()
       #    cn.close
    cn.commit()
    cn.close

ストアドプロシージャ

args = (_videoid, 0)
          result_args = c.callproc('work_schema.sp_put_copylist', args)

単純にポイントとしてはここだけです。

callprocで呼ぶ 引数は、argsにセット(0は、MySQLのプロシージャ内でOUT属性のための固定値)