sqlite3 not selecting anything when I use AND operator - python

I am trying to select something from the database in sqlite3.
import sqlite3
conn = sqlite3.connect("db_informatii_principal.db")
c = conn.cursor()
c.execute("CREATE TABLE persoane (id integer PRIMARY KEY, nume text, prenume text, telefon text, varsta text, adresa text, inaltime text, instagram text, detalii text)")
conn.commit()
c.execute("INSERT INTO persoane VALUES(NULL, 'Mustea', 'David', '0425698333', '17', 'Exemplu Adresa 1', '182', 'george.george', 'Ii place sa bea')")
conn.commit()
lista = ["David", "Mustea"]
c.execute(f"SELECT * FROM persoane WHERE nume = '{lista[0] or lista[1]}' AND prenume = '{lista[0] or lista[1]}'")
for x in c.fetchall():
print(x)
I am using the AND operator in sqlite3 and the or operator in f-string in python, and it's giving me no results.

Your f-string is substituting the Python expression lista[0] or lista[1], which will return "David". I suspect you wanted WHERE (name = '{lista[0]}' OR name = '{lista[1]}') AND (prenume = '{lista[0]}' OR prenume = '{lista[1]}'), but there are many better ways to do this. You should NEVER handle this kind of string substitution yourself. Let the database do it. It knows the quoting rules. Your code would fail, for example, if you looked for the name "O'Shea".
c.execute("SELECT * FROM persoane WHERE name IN (?,?) AND prenume IN (?,?);", lista + lista )

Related

"Delete from" deletes everything

I have a python function that deletes a row in mysql table using name attribute as a condition:
def delete(table: str, name: str):
cursor.execute(f"DELETE FROM {table} WHERE name = {name}")
conn.commit()
I have one row with a name attribute equal to "Name". When I use this function with "Name" it deletes every single row in a table.
I'm guessing that it has to do with passed string being same as attribute. But what would be the solution to that problem except renaming attributes?
So for one, I think you are missing quotes around name, as well as a semicolon.
For further reading you should also take a look at Python parameterized query and Prepared Statement
I do agree with the comments, that table should not be an injected argument for security reasons!
def delete(table: str, name: str):
query = f"DELETE FROM {table} WHERE name = ?"
print(query)
cursor.execute(query, (name,))
conn.commit()`
EDIT FULL WORKING EXAMPLE:
import sqlite3
conn = sqlite3.connect("test")
query_create = '''CREATE TABLE IF NOT EXISTS projects (
id integer PRIMARY KEY,
name text NOT NULL,
begin_date text,
end_date text
);'''
conn.execute(query_create)
query_insert = '''insert into projects (id, name, begin_date, end_date) values (1,"name","date","date")'''
conn.execute(query_insert)
query_select = '''select * from projects'''
cur = conn.execute(query_select)
print(cur.fetchall())
def delete(table: str, name: str):
query = f"DELETE FROM {table} WHERE name = ?"
print(query)
conn.execute(query, (name,))
delete('projects', 'name')
cur = conn.execute(query_select)
print(cur.fetchall())
Gives Output:
[(1, 'name', 'date', 'date')]
DELETE FROM projects WHERE name = ?
[]

is there a way to fix this error i am getting?

This is the frontend of my program. This a function to delete a set of records from a table. It gives me this error:project1Database.deleteRec(sd[0])
NameError: name 'sd' is not defined. I know it probably a little mistake by I am still new to coding so anything can help.
def EmployeeRec(event):
global sd
searchEmp = employeelist.curselection()[0]
sd = employeelist.get(searchEmp)
self.txtEmpID.delete(0,END)
self.txtEmpID.insert(0,sd[1])
self.txtFirstname.delete(0,END)
self.txtFirstname.insert(END,sd[2])
self.txtMiddlename.delete(0,END)
self.txtMiddlename.insert(END,sd[3])
self.txtLastname.delete(0,END)
self.txtLastname.insert(END,sd[4])
self.txtDob.delete(0,END)
self.txtDob.insert(END,sd[5])
self.txtNationality.delete(0,END)
self.txtNationality.insert(END,sd[6])
self.txtNI.delete(0,END)
self.txtNI.insert(END,sd[7])
self.txtAddres.delete(0,END)
self.txtAddres.insert(END,sd[8])
self.txtPostcode.delete(0,END)
self.txtPostcode.insert(END,sd[9])
self.txtphonenumber.delete(0,END)
self.txtphonenumber.insert(END,sd[10])
self.txtEmail.delete(0,END)
self.txtEmail.insert(END,sd[11])
self.txtPassportnumber.delete(0,END)
self.txtPassportnumber.insert(END,sd[12])
self.txtPassportexpirydate.delete(0,END)
self.txtPassportexpirydate.insert(END,sd[13])
self.txtgender.delete(0,END)
self.txtgender.insert(END,sd[14])
def deleteData():
if(len(EmpID.get())!=0):
project1Database.deleteRec(sd[0])
clearData()
displayData()
This is the backend. This is the table for my program.
import sqlite3
#backend
def employeeData():
conn = sqlite3.connect('projectv4.db')
c= conn.cursor()
c.execute("""CREATE TABLE IF NOT EXISTS employee(EmployeeID INTEGER PRIMARY KEY,EmpID text,
Firstname text,Middlename text, Lastname text,
Dob text, Nationality text, NI text, Addres text, Postcode text, phonenumber text,
Email text, Passportnumber text, Passportexpirydate text,
gender text)""")
conn.commit()
conn.close()
This is the function I am trying to call from my frontend:
def deleteRec(EmployeeID):
conn = sqlite3.connect('projectv4.db')
c= conn.cursor()
c.execute("DELETE FROM employee WHERE EmployeeID = ?", (EmployeeID,))
conn.commit()
conn.close()
deleteData refers to sd before initializing it. Assuming you mean the same global variable as in EmployeeRec, you need to explicitly state that it's global:
def deleteData():
if(len(EmpID.get())!=0):
global sd #here!
project1Database.deleteRec(sd[0])
clearData()
displayData()

Python SQLite3 function not printing any data

I have created a function that is supposed to send all the items, with a stock level of less than 10, in my database to a text file. But i am not receiving any data when I press the reorder button.
def Database():
global conn, cursor
conn = sqlite3.connect("main_storage.db")
cursor = conn.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS `admin` (admin_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, username TEXT, password TEXT)")
cursor.execute("CREATE TABLE IF NOT EXISTS `product` (product_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, product_name TEXT, product_qty TEXT, product_price TEXT)")
cursor.execute("CREATE TABLE IF NOT EXISTS `basket` (product_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, product_name TEXT, product_qty TEXT, product_price TEXT)")
cursor.execute("SELECT * FROM `admin` WHERE `username` = 'admin' AND `password` = 'admin'")
if cursor.fetchone() is None:
cursor.execute("INSERT INTO `admin` (username, password) VALUES('admin', 'admin')")
conn.commit()
def reorder():
global items
Database()
cursor.execute("SELECT `product_name` FROM `product` WHERE `product_qty` <= 10")
items = cursor.fetchall()
print(items)
cursor.close()
conn.close()
I expect the output to be an array of items within my database e.g. [44, 'motherboard', 9, 80] where 44 is product_id, motherboard is product_name, 9 is product_stock and 80 is product_price. I am actually getting an array with nothing in like: []
product_qty is defined as a TEXT column, so comparisons like <= will be performed between the string values of operands. This may not give the results that you expect:
>>> '8' < '10'
False
Recreate your tables with INTEGER or REAL as the column type for numeric values to get the behaviour that you want. For example:
cursor.execute("""CREATE TABLE IF NOT EXISTS `product` """
"""(product_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"""
"""product_name TEXT, product_qty INTEGER, product_price REAL)""")

python sqlite3 query with AND

I am trying to build a simple Address book GUI that has a wx.listbox, that holds all the names in the book, first and last. Once clicked, it will return the information attached to the name from a database file. Right now I have it working by just the last name, I am trying to match first and last names. I am not, really, familiar with the SQLite 3 commands and syntax.
The function is below, this works fine now, but I want to change the query to something like:
select * from AddressBook where Last like names[0] and First like names[1]
Any help would be great!
def onListBox(self, event):
name = event.GetEventObject().GetStringSelection()
names = name.split(',')###names[0]=Last name, names[1] = first name
cursor = db.cursor()
cursor.execute("select * from AddressBook where Last like ?",('%'+names[0]+'%',) )
result = cursor.fetchall()
return result
The query from your comment should work.
Here is a small working example:
import sqlite3
conn = sqlite3.connect("test.sql")
cursor = conn.cursor()
cursor.execute("create table address_book (first_name text, last_name text)")
names = [["John", "Smith"], ["Jane", "Smith"]]
for first_name, last_name in names:
cursor.execute("insert into address_book (first_name, last_name) values (?, ?)", (first_name, last_name))
cursor.execute("select * from address_book where first_name like ? and last_name like ?", ("%" + names[0][0] + "%", "%" + names[0][1] + "%"))
print(cursor.fetchall())
It prints:
[('John', 'Smith')]

How do I confine the output of a fetchall() on my table to just the value?

I have the following function:
def credential_check(username, password):
conn = sqlite3.connect('pythontkinter.db')
c = conn.cursor()
idvalue = c.execute('''SELECT ID FROM userdetails WHERE username = "{0}"'''.format(username)).fetchall()
print(idvalue)
I wish to assign the value of ID in my userdetails table to the variable idvalue in the row where the inputted username = userdetails username, however when I use this fetchall() I get [('0',)] printed out rather than just 0.
How do I go about doing this?
Thanks
You can use fetchone() if you only want one value. However, the result will still be returned as a tuple, just without the list.
import sqlite3
conn = sqlite3.connect('test.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS testing(id TEXT)''')
conn.commit()
c.execute("""INSERT INTO testing (id) VALUES ('0')""")
conn.commit()
c.execute("""SELECT id FROM testing""")
data = c.fetchone()
print data
# --> (u'0',)
You can also use LIMIT if you want to restrict the number of returned values with fetchall().
More importantly, don't format your queries like that. Get used to using the ? placeholder as a habit so that you are not vulnerable to SQL injection.
idvalue = c.execute("""SELECT ID FROM userdetails WHERE username = ?""", (username,)).fetchone()

Categories

Resources