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

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

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

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

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

2485閲覧

Tkinter入力値をMySQLに格納する方法

wakaba_

総合スコア1

MySQL

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

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1グッド

1クリップ

投稿2020/10/05 16:38

編集2020/10/07 19:17

Tkinterで注文管理のデスクトップアプリを作りたいと考えています。

色んなホームページからコピーペーストしているのですが、
Entryなどで入力したデータをMySQLに格納する方法がどうしても分かりません。

getで取得してから代入して、引数に入れてみたりしましたが実行できません。
送信ボタンを押すと、複数のデータが各指定の列に格納されるのをイメージしています。

初歩的な質問で恐縮ですが、ご教授いただけますと幸いです。

import tkinter as tk import tkinter.ttk as ttk import mysql.connector as mydb # ウィンドウ作成 root = tk.Tk() # タイトル root.title("入力") # サイズ root.geometry("400×400") # コネクションの作成 conn = mydb.connect( user='root', password='********', host='localhost', database='order_list') # DB操作用にカーソルを作成 cur = conn.cursor() order_date = entry.get() order_num = entry2.get() def create_sql() : cur.execute( INSERT INTO orders (orderDate, orderNum) VALUES (order_date, order_num)) # 日付 label = ttk.Label(root, text='日付') label.pack() entry = tk.Entry() entry.pack() # 注文番号 label2 = ttk.Label(root, text='注文番号') label2.pack() entry2 = tk.Entry() entry2.pack() # 送信 button = ttk.Button(root, text = "送信", command = create_sql()) button.pack() # 保存 conn.commit() # DB操作が終わったらカーソルとコネクションを閉じる cur.close() conn.close() # ウィンドウを動かす root.mainloop()

追記1

import tkinter as tk import tkinter.ttk as ttk import mysql.connector as mydb root = tk.Tk() root.title("入力") root.geometry("400x400") # コネクションの作成 conn = mydb.connect( host='localhost', user='root', password='********', database='order_list' ) # 接続状況 conn.ping(reconnect=True) print(conn.is_connected()) # DB操作用にカーソルを作成 cur = conn.cursor() # 日付 label = ttk.Label(root, text='日付') label.pack() entry = ttk.Entry() entry.pack() # オーダーNo. label2 = ttk.Label(root, text='注文番号') label2.pack() entry2 = ttk.Entry() entry2.pack() # クエリ def create_sql() : order_date = entry.get() order_num = entry2.get() cur.execute('INSERT INTO orders (%(orderDate)s, %(orderNum)s) VALUES (%(orderDate)s, %(orderNum)s)', {'orderDate': orderDate, 'orderNum': orderNum}) conn.commit() # 送信 button = ttk.Button(root, text = "送信", command = create_sql) button.pack() # DB操作が終わったら、カーソルとコネクションを閉じる cur.close() conn.close() # ウィンドウを動かす root.mainloop()

エラー

True Exception in Tkinter callback Traceback (most recent call last): File "C:\Users*****\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 1883, in __call__ return self.func(*args) File "C:\Users*****\Desktop\Python\test.py", line 41, in create_sql cur.execute('INSERT INTO input (%(orderDate)s, %(orderNum)s) VALUES (%(orderDate)s, %(orderNum)s)', {'orderDate': order_date, 'orderNum': order_num}) File "C:\Users*****\AppData\Local\Programs\Python\Python38-32\lib\site-packages\mysql\connector\cursor.py", line 537, in execute raise errors.ProgrammingError("Cursor is not connected") mysql.connector.errors.ProgrammingError: Cursor is not connected

宜しくお願い致します。


追記2 closeをGUI終了後にした場合

import tkinter as tk import tkinter.ttk as ttk import mysql.connector as mydb # ウィンドウ root = tk.Tk() root.title("入力") root.geometry("400x400") # コネクション作成 conn = mydb.connect( host='localhost', user='root', password='*******', database='order_list') # カーソル作成 cur = conn.cursor() # 日付 label = ttk.Label(root, text='日付') label.pack() entry = ttk.Entry() entry.pack() # オーダーNo. label2 = ttk.Label(root, text='オーダーNo.') label2.pack() entry2 = ttk.Entry() entry2.pack() # クエリ def create_sql() : order_date = entry.get() order_num = entry2.get() cur.execute('INSERT INTO orders (%(orderDate)s, %(orderNum)s) VALUES (%(orderDate)s, %(orderNum)s)', {'orderDate': orderDate, 'orderNum': orderNum}) # 送信 button = ttk.Button(root, text = "送信", command = create_sql) button.pack() # 保存 conn.commit() # ウィンドウを動かす root.mainloop() # カーソルとコネクションを閉じる cur.close() conn.close()

エラー

Exception in Tkinter callback Traceback (most recent call last): File "C:\Users*****\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 1883, in __call__ return self.func(*args) File "C:\Users*****\Desktop\Python\test.py", line 39, in create_sql {'orderDate': orderDate, 'orderNum': orderNum}) NameError: name 'orderDate' is not defined

入力値を代入した、

order_date = entry.get() order_num = entry2.get()

をVALUEに渡せていないように思えるのですが、

def create_sql() : order_date = entry.get() order_num = entry2.get() cur.execute('INSERT INTO orders (%(orderDate)s, %(orderNum)s) VALUES (%(orderDate)s, %(orderNum)s)', {'orderDate': order_date, 'orderNum': order_num})

に変えるとエラーが変わり、

mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''20201008', '975022') VALUES ('20201008', '975022')' at line 1

と表示されます。MySQLで、下記は作成済です。

データベース order_list
テーブル orders
カラム orderDate, orderNum


MySQL再起動の上、下記コードに変えたところ入力値が格納されていました。

import tkinter as tk import tkinter.ttk as ttk import mysql.connector as mydb # コネクション作成 conn = mydb.connect( host='localhost', user='root', password='********', database='order_list') # カーソル作成 cur = conn.cursor() # SQL def create_sql() : order_date = entry.get() order_num = entry2.get() cur.execute('INSERT INTO orders (orderDate, orderNum) VALUES (%(order_date)s, %(order_num)s)', {'order_date': order_date, 'order_num': order_num}) conn.commit() # ウィンドウ root = tk.Tk() root.title("入力") root.geometry("400x400") # 日付 label = ttk.Label(root, text='日付') label.pack() entry = ttk.Entry() entry.pack() # オーダーNo. label2 = ttk.Label(root, text='オーダーNo.') label2.pack() entry2 = ttk.Entry() entry2.pack() # 送信 button = ttk.Button(root, text = "送信", command = create_sql) button.pack() # ウィンドウを動かす root.mainloop() # カーソルとコネクションを閉じる cur.close() conn.close()
teamikl👍を押しています

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

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

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

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

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

kairi003

2020/10/05 16:53

これentryとentry2が定義前に参照されてますけどエラーにならないんですか?
wakaba_

2020/10/05 17:10 編集

ご指摘ありがとうございます。 order_date = entry.get() order_num = entry2.get() def create_sql() : cur.execute( INSERT INTO orders (orderDate, orderNum) VALUES (order_date, order_num)) 上記を#送信の上に移動してみましたが、やはり実行できませんでした…
t_obara

2020/10/06 00:20

どのようになるので、実行できないのかご提示ください。
wakaba_

2020/10/06 18:43 編集

import tkinter as tk import tkinter.ttk as ttk import mysql.connector as mydb root = tk.Tk() root.title("入力") root.geometry("400x400") # コネクションの作成 conn = mydb.connect( host='localhost', user='root', password='********', database='order_list' ) # 接続状況 conn.ping(reconnect=True) print(conn.is_connected()) # DB操作用にカーソルを作成 cur = conn.cursor() # 日付 label = ttk.Label(root, text='日付') label.pack() entry = ttk.Entry() entry.pack() # オーダーNo. label2 = ttk.Label(root, text='注文番号') label2.pack() entry2 = ttk.Entry() entry2.pack() # クエリ def create_sql() : order_date = entry.get() order_num = entry2.get() cur.execute('INSERT INTO orders (%(orderDate)s, %(orderNum)s) VALUES (%(orderDate)s, %(orderNum)s)', {'orderDate': orderDate, 'orderNum': orderNum}) conn.commit() # 送信 button = ttk.Button(root, text = "送信", command = create_sql) button.pack() # DB操作が終わったら、カーソルとコネクションを閉じる cur.close() conn.close() # ウィンドウを動かす root.mainloop() 上記で実行したところ、ウィンドウは出るようになったのですが、下記のエラーが出ます。 True Exception in Tkinter callback Traceback (most recent call last): File "C:\Users\*****\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 1883, in __call__ return self.func(*args) File "C:\Users\*****\Desktop\Python\test.py", line 41, in create_sql cur.execute('INSERT INTO input (%(orderDate)s, %(orderNum)s) VALUES (%(orderDate)s, %(orderNum)s)', {'orderDate': order_date, 'orderNum': order_num}) File "C:\Users\*****\AppData\Local\Programs\Python\Python38-32\lib\site-packages\mysql\connector\cursor.py", line 537, in execute raise errors.ProgrammingError("Cursor is not connected") mysql.connector.errors.ProgrammingError: Cursor is not connected
wakaba_

2020/10/06 18:42

def create_sql() : order_date = entry.get() order_num = entry2.get() cur.execute('INSERT INTO input (orderDate, orderNum) VALUES (%(orderDate)s, %(orderNum)s)', {'orderDate': order_date, 'orderNum': order_num}) conn.commit() # クエリを上記に変えてみましたが、同じエラーが出ました。 mysql.connector.errors.ProgrammingError: Cursor is not connected
teamikl

2020/10/07 05:34

エラー原因はclose 済みのカーソルに対して操作してる事だと思いますが、 今の質問に書かれてるコードでは再現できませんし、 上記のエラー以外の問題が複数あります。 ボタンクリック時のコールバック登録や、SQL が文字列になっていない、等。 ここのコメント中のソースコードではインデントを把握できないので、 質問文を編集して、ソースコードとエラー内容を追記できますか。
teamikl

2020/10/07 17:24

create_sql 関数のインデントが崩れたままです。 一カ所だけなので推測可能な範囲ですが、 質問の際は、エラーと問題のエラーを再現できるコードを示さないと、 有益な回答を得られない場合があるので注意してください。 一番最初に掲載されたコードで起こるエラーでは、 create_sql が呼ばれるタイミングが今のコードとは違っていたので、 kairi003さんの回答で解決となっていたはずです。 ボタンへの登録 command = create_sql() の部分が修正されたことにより 別のエラーが起こる様になってました。 私の回答は後から起こった Cursor is not connected に対するものです。
wakaba_

2020/10/07 19:00

至らない点が多く、申し訳ありません。 ご指摘いただきありがとうございます。分かりやすい回答で非常に勉強になりました。 いただいた回答を元に修正しましたが、別のエラーが出ました。 追記しましたのでご確認の程宜しくお願い致します。
guest

回答3

0

エラー内容

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''20201008', '975022') VALUES ('20201008', '975022')'

SQLの構文エラーです。
VALUES 前のカラム名の所まで値になってるようなので、正しいクエリに修正します。

diff

1- INSERT INTO orders (%(orderDate)s, %(orderNum)s) VALUES (%(orderDate)s, %(orderNum)s) 2+ INSERT INTO orders (orderDate, orderNum) VALUES (%(orderDate)s, %(orderNum)s)

投稿2020/10/07 19:39

teamikl

総合スコア8664

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

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

teamikl

2020/10/07 19:57

投稿が入れ違いになったようです。3つ目のエラーは自己解決されたようですね。 {'orderDate': order_date, 'orderNum': order_num} の変数の部分は、 create_sql 関数内で作られたローカル変数なので、 変数名をテーブルのプレースホルダの名前(%(name)s の中の名前)と同じにすると、 locals() と置き換える事もできます。 あと気になる点、プレースホルダの値の型について orderNum が %(...)s <-- string(文字列型)として扱われる? %(...)d だと 数値になりますが、Entry から得られるのは文字列なので、 入力が数値以外の場合の対応が必要になるかもしれません。 もし、GUIの入力を数値にしたい場合は tkinter の IntVarの使い方も調べて見て下さい。
wakaba_

2020/10/08 15:23

知らないことばかりで大変勉強になりました。ようやく次に進めます。 親身に教えていただき、本当にありがとうございました。
guest

0

ベストアンサー

python

1#送信 2button = ttk.Button(root, text = "送信", command = create_sql) 3button.pack() 4 5# 保存 6conn.commit() 7 8# DB操作が終わったらカーソルとコネクションを閉じる 9cur.close() 10conn.close() 11 12# ウィンドウを動かす 13root.mainloop()

問題点: close 済みの cursor に対する操作

DB操作が終わったらカーソルとコネクションを閉じる

とコメントにありますが、この時点ではDB操作は行われてません。

上記のコードでは、GUI 表示前に cur, conn が閉じられています。
create_sql() が呼ばれるのは、イベント処理を行うmainloop内です。

対策 (どちらか):

  • close は GUI終了後にする
  • cur 作成を create_sql 内にする

ボタンを押す度に毎回接続するか、アプリケーション起動中は接続を維持するかは
用途により使い分けて下さい。外部データベースへの接続はタイムアウトがある点も注意。

投稿2020/10/07 17:13

teamikl

総合スコア8664

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

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

0

これでどうですかね?
get()が実行された時点で内容が参照されると思うので元のコードでは最初に表示された空欄(多分)の状態しか取得できていないと思います。
ボタンを押した瞬間の内容を取得できないと意味ないです。

py

1def create_sql() : 2 order_date = entry.get() 3 order_num = entry2.get() 4 cur.execute( 5 'INSERT INTO orders (%(orderDate)s, %(orderNum)s) VALUES (%(orderDate)s, %(orderNum)s)', {'orderDate': orderDate, 'orderNum': orderNum})

投稿2020/10/05 17:26

編集2020/10/05 17:32
kairi003

総合スコア1330

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

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

wakaba_

2020/10/05 17:43

書いていただいたコードで試してみましたが、ダメでした… 今いる行番号がエラー表示され、実行できない状態です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問