前提・実現したいこと
pythonのmysql-connectorのexecutemany()のメソッドを利用して、
パラメータで副問合せを実行する方法を知りたいです。
DBのテーブルは「社員テーブル」、「顧客テーブル」の2つがあります。
「顧客テーブル」にデータを登録する際
「同じ社員ID」がある場合、「sort_no」は「最大値+1」を設定値とする
発生している問題・エラーメッセージ
Eさんを登録した時に、「sort_no」が「3」ではなく「0」になってしまいます。
sql
1-- 処理実行前 2mysql> SELECT * FROM customer; 3+----+-------------+---------+---------+ 4| id | employee_id | name | sort_no | 5+----+-------------+---------+---------+ 6| 1 | 1 | Aさん | 1 | 7| 2 | 1 | Cさん | 2 | 8| 3 | 2 | Bさん | 1 | 9| 4 | 3 | Dさん | 1 | 10+----+-------------+---------+---------+ 114 rows in set (0.00 sec) 12 13 14-- 処理実行後 15mysql> SELECT * FROM customer; 16+----+-------------+---------+---------+ 17| id | employee_id | name | sort_no | 18+----+-------------+---------+---------+ 19| 1 | 1 | Aさん | 1 | 20| 2 | 1 | Cさん | 2 | 21| 3 | 2 | Bさん | 1 | 22| 4 | 3 | Dさん | 1 | 23| 5 | 1 | Eさん | 0 | 24+----+-------------+---------+---------+ 255 rows in set (0.00 sec)
該当のソースコード
gitにもありますが、こちらにも掲載します。
python
1 config = { 2 'host': 'sample_my' 3 ,'port': '3306' 4 ,'user': 'root' 5 ,'password': 'root' 6 ,'database': 'table1' 7 } 8 9 cnx = connector.connect(**config) 10 11 cnx.ping(reconnect=True) 12 # 自動コミットオフ 13 cnx.autocommit = False 14 # カーソル作成 15 cur = cnx.cursor() 16 17 ''' 18 顧客テーブルに新たにデータ登録 19 sort_noは副問合せで取得して設定 20 ''' 21 # 副問合せをパラメータとして設定 22 values = [ 23 (1, 'Eさん', '(SELECT MAX(sort_no)+1 AS `max_sort_no` FROM customer WHERE employee_id = 1)') 24 ] 25 26 # TODO: 設定するも「0」が登録される 27 # 最大値+1で「3」が設定される想定 28 cur.executemany(""" 29 INSERT INTO `customer` (employee_id, name, sort_no) VALUES 30 (%s, %s, %s); 31 """, values) 32 cnx.commit() 33 34 exit()
試したこと
いくつか別の方法で試した際には期待してる結果になることを確認しました。
python
1# 以下をmain.pyの38行目以降に追加 2 ''' 3 念のため、別の方法で実施 4 ''' 5 6 # 全て文字列で実行 7 # 想定通りに登録される 8 cur.execute(""" 9 INSERT INTO `customer` (employee_id, name, sort_no) VALUES 10 (1, 'Fさん', (SELECT MAX(sort_no)+1 FROM customer AS `c` WHERE employee_id = 1)); 11 """) 12 cnx.commit() 13 14 # 先に取得して、文字列に組み込み 15 cur.execute("SELECT MAX(sort_no)+1 AS `max_sort_no` FROM customer WHERE employee_id = 1;") 16 sort_no = cur.fetchall()[0][0] 17 18 # 想定通りに登録される 19 cur.execute(f""" 20 INSERT INTO `customer` (employee_id, name, sort_no) VALUES 21 (1, 'Gさん', {sort_no}); 22 """) 23 cnx.commit() 24 25 # 先に取得して、パラメータとして設定 26 cur.execute("SELECT MAX(sort_no)+1 AS `max_sort_no` FROM customer WHERE employee_id = 1;") 27 sort_no = cur.fetchall()[0][0] 28 values = [ 29 (1, 'Hさん', sort_no) 30 ] 31 32 # 想定通りに登録される 33 cur.executemany(""" 34 INSERT INTO `customer` (employee_id, name, sort_no) VALUES 35 (%s, %s, %s); 36 """, values) 37 cnx.commit()
実行結果確認
sql
1mysql> SELECT * FROM customer; 2+----+-------------+---------+---------+ 3| id | employee_id | name | sort_no | 4+----+-------------+---------+---------+ 5| 1 | 1 | Aさん | 1 | 6| 2 | 1 | Cさん | 2 | 7| 3 | 2 | Bさん | 1 | 8| 4 | 3 | Dさん | 1 | 9| 5 | 1 | Eさん | 0 | 10| 6 | 1 | Eさん | 0 | 11| 7 | 1 | Fさん | 3 | 12| 8 | 1 | Gさん | 4 | 13| 9 | 1 | Hさん | 5 | 14+----+-------------+---------+---------+ 159 rows in set (0.00 sec)
補足情報(FW/ツールのバージョンなど)
環境は下記になります。
Docker Engine v20.10.7 Python 3.10.0 mysql-connector 2.2.9 mysql 8.0.0
コンテナ構築、ソースコードなどのgitはこちら
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/11/22 00:34