Code:
from tkinter import *
import tkinter as tk
import mysql.connector
def main():
root = tk.Tk()
app = MainWindow(root)
root.mainloop()
class mySQL:
def __init__(self):
#MySQL Credentials
self.db = mysql.connector.connect(
host="XXXX-XX99",
user="root",
passwd="TEST",
database="technical")
#Cursor
self.cursor = self.db.cursor()
def simple_query(self,sql):
self.cursor.execute(sql)
class MainWindow:
def __init__(self,master):
self.master = master
self.master.state('zoomed')
self.master.geometry('400x700')
self.frame = Frame(self.master)
self.frame.pack(fill="both", expand=True)
#Entries and text-box
self.nameLabel = Label(self.frame, text = "Name of Person Making Request:")
self.nameEntry = Entry(self.frame)
# Buttons
self.btn = Button(self.frame, text = "Submit", command = self.sendData)
# Organizing above^
self.nameLabel.pack()
self.nameEntry.pack()
self.btn.pack()
def sendData(self):
x = mySQL()
#Values
values = (
self.nameEntry.get(),
)
#Insert Command
x.simple_query("INSERT INTO document_control (person) values ('%s')", values)
if __name__ == '__main__':
main()
Goal:
Inside my class mySQL
and function simple_query(self,sql)
is used in my class MainWindow
at function sendData(self)
. (see x.query("INSERT..."
) I am trying to make this work, simply insert values into MySQL.
When I press the button submit
- (activates function sendData(self)
) error comes up with:
TypeError: simple_query() takes 2 positional arguments but 3 were given
I am not quite sure why the output is TypeError.
Where Im I going wrong here? Which section of the code do I need to change? And what needs changing?
def simple_query(self, sql):
self.cursor.execute(sql)
and
x.simple_query("INSERT INTO document_control (person) values ('%s')", values)
Here you are passing 2 arguments to simple_query
(the query string and values
) but it only accepts one, sql
(self
is the instance, in this case x
, and is passed implicitly).
Other answers make your code work, but they also make it vulnerable to SQL injection.
For example, if someone were to enter the string a'); delete from document_control; --
in the GUI then the executed query will be
INSERT INTO document_control (person) values ('a'); delete from document_control; -- ')
Not so good...
Instead of using string interpolation you should use a parameterized query. It can be done by allowing simple_query
to accept an optional arguments
tuple.
def simple_query(self, sql, args=None):
if not args:
self.cursor.execute(sql)
else:
self.cursor.execute(sql, args)
Keep in mind that args
should be a tuple or a list.