質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

2181閲覧

python, mysql-connectorのexecutemany()のパラメータで副問合せを実行する方法

k.a_teratail

総合スコア845

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2021/11/21 10:32

編集2021/11/21 11:26

前提・実現したいこと

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はこちら

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

プレースホルダはしか受け付けませんので、サブクエリ全体を後から「値」としてセットして実行することはできません。

投稿2021/11/21 11:33

maisumakun

総合スコア145208

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

k.a_teratail

2021/11/22 00:34

> プレースホルダは値しか受け付けませんので、サブクエリ全体を後から「値」としてセットして実行することはできません。 「name」にサブクエリを仕込むと、文字列で登録されていることが確認できました。 executemany()のパラメータでサブクエリを使用することは不可能ということですね ```sql *************************** 10. row *************************** id: 10 employee_id: 1 name: (SELECT MAX(sort_no) sort_no: 1 ``` サブクエリ値をパラメータとして使用するなら 先に取得して、設定するかないということですね。 ご回答いただき、ありがとうございました。 こちらをベストアンサーとして、質問をクローズします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問