Python- How to compare strings between an access db and a variable? - python

from tkinter import *
import tkinter as tk
import pyodbc
root1 = tk.Tk()
label1 = tk.Label(root1, text='product A')
input1 = StringVar()
entry1 = tk.Entry(root1,textvariable=input1)
label1.pack(side = tk.TOP)
entry1.pack()
buttonstr = tk.StringVar()
db = r"C:\Users\Goutham\Documents\keshav\testdb.accdb"
def odbc():
'''
connects with odbc
'''
constr = 'Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=' + db
conn = pyodbc.connect(constr, autocommit=True)
cur = conn.cursor()
check=input1.get()
strsql = "select * from student where SName=%s"%(check)
cur.execute(strsql)
results = cur.fetchall()
print (results,check)
conn.close()
buttonA = tk.Button(text = "hello", command = odbc)
buttonA.pack()
I need this code to get input,store it in the variable -'check' and compare it with the values in the database using a SQL query.The matching values from the database are then displayed.
There seems to be a problem in the implementation of the SQL query.'check' stores the value of the input. The SQL query does not work properly and causes errors.
Please help.
Thank you.

You need to single quote the parameter to the WHERE clause:
strsql = "select * from student where SName='%s'" % (check,)
But be careful with building clauses like this (using string formatting), you run the risk of SQL injection. You should pass parameters instead:
strsql = "select * from student where SName=?"
cur.execute(strsql, (check,))

Related

Python + MySQL: Search function returning all entries

I'm putting together an inventory program using Python and MySQL. I want to implement a search function that returns entries based on user input (programmed in a separate GUI file). In the code below, I expected that the search function would return entries with the brand "UGreen". Instead, it returns all of the entries in the table.
I'm not sure what I'm doing wrong here. I have used a similar structure in another program with a sqlite database instead and the search worked fine.
Any and all help/suggestions would be greatly appreciated :)
import mysql.connector
equipdb = mysql.connector.connect(
host = "localhost",
user = "root",
password = "REDACTED",
database = "tel_inventory"
)
def view():
cur = equipdb.cursor()
cur.execute("SELECT * FROM equipment")
result = cur.fetchall()
return result
def search(name="", brand="", model="", consumables="", storage="", room="", photo=""):
cur = equipdb.cursor()
cur.execute("SELECT * FROM equipment WHERE name=%s OR brand=%s OR model=%s OR consumables=%s OR storage=%s OR room=%s OR photo=%s", (name, brand, model, consumables, storage, room, photo))
result = cur.fetchall()
return result
#print(view())
print(search(brand="UGreen"))
Try using keyword argument directly
def search(**kwargs):
cur = equipdb.cursor()
key = str(list(kwargs.keys())[0])
value = str(kwargs[key])
cur.execute('SELECT * FROM equipment WHERE {} = "{}"'.format(key,value))
result = cur.fetchall()
return result

Python / Access NameError: name '' is not defined

I am trying to rewrite some old Access VBA codes to Python but I stuck with the following error:
NameError: name 'ERTZ6635' is not defined
Old VBA Code
Set ConsTable = DB.OpenRecordset("SELECT * FROM table1")
ConsCount = 87404
If ConsCount > 0 Then
ConsTable.MoveFirst
For I = 1 To ConsCount
Set ConsBlendTable = DB.OpenRecordset("SELECT * FROM table2 WHERE CONS_BATCH = " & Char34(ConsTable!Batch))
Python code:
import win32com.client
dbe = win32com.client.Dispatch("DAO.DBEngine.120")
db = dbe.OpenDatabase(r"C:\Users\xyz\Desktop\acess.accdb")
ConsTable = db.OpenRecordset("select * from table1")
ConsCount = 87404
if ConsCount>0:
ConsTable.MoveFirst()
for i in range(1, ConsCount):
ConsBlendTable = db.OpenRecordset("SELECT * FROM table2 WHERE CONS_BATCH = " & eval(ConsTable.Fields["Batch"].Value))
And the ERTZ6635 value is the value in ConsTable.Fields["Batch"].Value
In the VBA code, Char34() likely is a user-defined function since it is not a VBA built-in method. There is however a constant Chr34 for the 34th character in the ASCII table for double quotes. So by its name, this method may wrap double quotes around the input parameter value. This is important since you attempt to translate in Python with eval.
So simple answer is to include double quotes which you can interpolate with F-strings in Python.
sql = f"""SELECT * FROM table2
WHERE CONS_BATCH = "{ConsTable.Fields["Batch"].Value}"
"""
ConsBlendTable = db.OpenRecordset(sql)
However, this string interpolation of parameters into an SQL query is not advisable in any language including VBA and Python. Aside from security and efficiency issues, this code can still break if value itself contains double quotes.
Instead, consider parameterization which is supported in MS Access SQL engine via QueryDefs.
VBA (adjusted from earlier SQL concatenation)
Dim qdef As QueryDef
...
Set ConsTable = DB.OpenRecordset("SELECT * FROM table1")
' PREPARED STATEMENT (NO DATA)
sql = "PARAMETERS batch_prm TEXT(255);" _
& "SELECT * FROM table2 WHERE CONS_BATCH = batch_prm"
ConsTable.MoveFirst
Do While Not ConsTable.EOF
Set qdef = DB.CreateQueryDef("", sql)
qdef!batchprm = ConsTable!Batch ' BIND PARAMETER
Set ConsBlendTable = qdef.OpenRecordset() ' OPEN RECORDSET VIA QUERYDEF
...
ConsBlendTable.Close
ConsTable.MoveNext
Loop
ConsTable.Close
'RELEASE RESOURCES
Set ConsBlendTable = Nothing: Set ConsTable = Nothing
Set qdef = Nothing: Set DB = Nothing
Python (employing try/except for proper COM handling)
Therefore in Python, we similarly interface with QueryDef object. Below loops through every record in recordset with traditional DAO loop (i.e., translation of Do While Not rst.EOF).
import win32com.client
try:
dbe = win32com.client.Dispatch("DAO.DBEngine.120")
db = dbe.OpenDatabase(r"C:\Users\xyz\Desktop\acess.accdb")
ConsTable = db.OpenRecordset("SELECT * FROM table1")
# PREPARED STATEMENT
sql = """PARAMETERS batch_prm TEXT(255);
SELECT * FROM table2 WHERE CONS_BATCH = batch_prm
"""
ConsTable.MoveFirst()
while ConsTable.EOF == False:
qdef = db.CreateQueryDef("", sql)
# BIND PARAMETER
qdef.Parameters["batch_prm"].Value = ConsTable.Fields["Batch"].Value
# OPEN RECORDSET VIA QUERYDEF
ConsBlendTable = qdef.OpenRecordset()
...
ConsBlendTable.Close()
ConsTable.MoveNext()
ConsTable.Close()
except Exception as e:
print(e)
finally:
# RELEASE RESOURCES
ConsBlendTable = None; ConsTable = None
qdef = None; db = None; dbe = None
del ConsBlendTable; del ConsTable; del qdef; del db; del dbe
Finally, I must note. Instead of direct translation of VBA, use Python's DB-API since it can directly query MS Access databases without DAO or COM objects, specifically with the well-maintained: pyodbc. And run with a JOIN instead of iterative loops via WHERE. And yes, pyodbc supports parameters with ? qmarks.
import pyodbc
dbname = r"C:\Users\xyz\Desktop\acess.accdb"
constr = f"DRIVER={{Microsoft Access Driver (*.mdb, *.accdb)}};DBQ={dbname};"
conn = pyodbc.connect(constr)
cur = conn.cursor()
sql = """SELECT t1.Batch, t2.CONS_BATCH, ...
FROM table1 t1
INNER JOIN tbale2 t2
ON t1.Batch = t2.CONS_BATCH
"""
cur.execute(sql)
for row in cur.fetchall():
...
cur.close()
conn.close()

Empty entries filled in MySQL table - Python > Tkinter

Empty entries filled in MySQL tables (Python + Tkinter)
Having a problem of data entry in MySQL. At the time of entry it don't take any value from me or
user. And one more thing I want to add multiple pages. But how can I make button to submit the value and direct to page 2. please if anyone know then please me.
Thank you
Here he the table which is completely empty.
from tkinter import *
import mysql.connector
from PIL import Image,ImageTk
m=Tk()
button_bg='#FF9200'
button_fg='#fff'
active_button_fg='#FF9200'
active_button_bg='#fff'
def tkinter_setup():
m.geometry('1024x720')
def database_connectivity():
FullName=StringVar()
CollegeName=StringVar()
Email = StringVar()
Password=IntVar()
CGPA= IntVar()
fullName=FullName.get()
collegeName=CollegeName.get()
email=Email.get()
password=Password.get()
cgpa=CGPA.get()
mydb = mysql.connector.connect(host="localhost", user="root", passwd="ashu12",database='mySchool')
cursor=mydb.cursor()
cursor.execute('CREATE TABLE IF NOT EXISTS Student (FullName TEXT,CollegeName TEXT,Email TEXT,Password INT,CGPA INT)')
cursor.execute('INSERT INTO Student (FullName,CollegeName,Email,Password,CGPA) VALUES(%s,%s,%s,%s,%s)',(fullName,collegeName,email,password,cgpa))
mydb.commit()
def page2():
entry7 = Entry(m,width=70)
entry7.place(x=0,y=30)
entry7.insert(0,'Full Name')
m.mainloop()
def page1():
Image_open=Image.open("1.png")
image=ImageTk.PhotoImage(Image_open)
logo=Label(m,image=image)
logo.place(x=0,y=0,bordermode="outside")
entry1 = Entry(m,textvar='FullName',font="Ubuntu")
entry1.place(height=45,width=397,x=145,y=154)
entry1 = Entry(m,width=42,textvar='Collegename',font="Ubuntu")
entry1.place(height=45,width=397,x=145,y=210)
entry1 = Entry(m,width=42,textvar='Email',font="Ubuntu")
entry1.place(height=45,width=397,x=145,y=266)
entry1 = Entry(m,width=42,textvar='Password',font="Ubuntu")
entry1.place(height=45,width=397,x=145,y=322)
entry1 = Entry(m,width=42,textvar='CGPA',font="Ubuntu")
entry1.place(height=45,width=397,x=145,y=377)
button = Button(m,text='Registration' , bg=button_bg,foreground=button_fg,activebackground=active_button_bg,activeforeground=active_button_fg,command=page2 )
button.place(height=47, width=399 ,x=144,y=476)
m.mainloop()
tkinter_setup()
database_connectivity()
page1()
page2()

How to create search form using tkinter Python to search from the SQLITE3 Database?

I want to use Tkinter to create a search form where the user can input the name they want to see from the SQLite3 database. A database named New_Assignment has all the details about the person. But I am confused about how to connect the Tkinter to the database and use the name to search? This is what I have got so far.
import sqlite3
conn = sqlite3.connect('new_assignment.db')
c = conn.cursor()
from tkinter import *
top = Tk()
top.title('Search form')
person_name = Entry()
person_name.pack(side = RIGHT, expand = True)
mainloop()
To get the text from the Entry widget, use the get() method (it returns the string in the textbox).
name_box = Entry()
name_box.pack(side=RIGHT, expand=True)
person_name = name_box.get()
However, you will need to add a button as #abarnert says in the comments. Attach this function to it:
def get_name():
global person_name
person_name = name_box.get()
data = c.fetchall()
print(data)
for row in data:
searchlist.append(row)
var1=str(person_name)
read_from_db(var1)
(Of couse, modify read_from_db() to take a variable like so:
def read_from_db(var):
curs.execute("SELECT *" + " FROM personal WHERE Name LIKE (?)", ('%'+var+'%',))
)
An example of the code for a button might look like this:
button = Button(top, text="Display text", command=get_name)
Place it all together:
import sqlite3
conn = sqlite3.connect('new_assignment.db')
c = conn.cursor()
from tkinter import *
top = Tk()
top.title('Search form')
name_box = Entry()
name_box.pack(side = RIGHT, expand = True)
def get_name():
global person_name
person_name = name_box.get()
data = c.fetchall()
print(data)
for row in data:
searchlist.append(row)
var1=str(person_name)
read_from_db(var1)
def read_from_db(var):
curs.execute("SELECT *" + " FROM personal WHERE Name LIKE (?)", ('%'+var+'%',))
person_name = ""
button = Button(top, text="Display text", command=get_name)
button.pack()
mainloop()

How to query from sqlite3 database if content in the entry match small requirement

I want to querying data from sqlite3 db from python and populate it in a Listbox but if am doing the search i have to provide the full name like Harvard University before the records can be inserted into the Listbox.
I want to query record like Harvard University by providing only Harvard then it will output all records with Havard content in it for me because if i don't provide full name it will not populate the listbox with any record.
Your suggestions are welcome to achieve this.
import tkinter as tk
import sqlite3
conn = sqlite3.connect("STATS.db")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS institution(id INTEGER PRIMARY KEY,
name TEXT)")
conn.commit()
conn.close()
def query_record():
data1 = e1_search.get()
conn = sqlite3.connect("STATS.db")
cur = conn.cursor()
cur.execute("SELECT * FROM institution WHERE name=?", (data1,))
row = cur.fetchall()
for n in row:
List.insert(tk.END, n)
print(n)
conn.close()
root = tk.Tk()
root.geometry("300x300")
List = tk.Listbox(root, width=100)
List.pack()
e1_search = tk.StringVar()
e1 = tk.Entry(root, textvariable=e1_search)
e1.pack()
b = tk.Button(text="Search", command=query_record)
b.pack(side=tk.BOTTOM)
root.mainloop()
I think you may have to modify the query.
Since "SELECT * FROM institution WHERE name=?", (data1,)
will exactly match the input string you can try with,
"SELECT * FROM institution WHERE name like ?", (data1+'%',).
Hope this works!

Categories

Resources