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')]
Related
I'm trying to create a contact book as a personal project. In the 'find_contact()' function, when I use the 'emaiL' variable to perform a query, it error message says that the data (I pre-recorded in the table) doesn't exist. But when I changed the variable to be used to query to 'phoneNum' (which is a number in text form) the query worked. How do I go about this please?
import sqlite3
conn = sqlite3.connect('contactBook.db')
cur = conn.cursor()
records = cur.fetchall()
#create table
cur.execute("""CREATE TABLE IF NOT EXISTS contacts (
first_name TEXT NOT NULL,
last_name TEXT,
phone_number TEXT NOT NULL PRIMARY KEY,
email,
address TEXT,
UNIQUE(phone_number, email)
)""")
#conn.close()
def save_contact():
save_contact.firstName = input("First name of contact: ")
lastName = input("Last name of contact: ")
phoneNumber = input("Phone number of contact: ")
email_ = input("Email of contact: ")
address_ = input("Address of contact: ")
cur.execute("INSERT OR IGNORE INTO contacts (first_name, last_name,phone_number,
email,address) VALUES (?, ?, ?, ?, ?)",
(save_contact.firstName, lastName, phoneNumber, email_, address_))
conn.commit()
def find_contact():
emaiL = input('Enter email: ')
query = f'''SELECT * FROM contacts WHERE email = {emaiL}'''
lua = f'''SELECT first_name, phone_number FROM contacts WHERE email = {emaiL}'''
#cur.execute("SELECT * FROM contacts (email) VALUES (?)", (email,))
cur.execute(query)
#conn.commit()
print(cur.execute(lua))
req = input("Hello, would you like to save or search for a contact: ")
if str.lower(req) == 'save':
save_contact()
x = save_contact.firstName
print("You have successfully saved " + x + "'s details")
elif str.lower(req) == 'search':
find_contact()
The test run was:
Hello, would you like to save, search or update for a contact:
search
Enter email: mine
The traceback:
Traceback (most recent call last):
File "c:\Users\GLORIA\Desktop\MINE\db.py", line 60, in <module>
find_contact()
File "c:\Users\GLORIA\Desktop\MINE\db.py", line 33, in
find_contact
cur.execute(query)
sqlite3.OperationalError: no such column: mine
query = f'''SELECT * FROM contacts WHERE email = {emaiL}'''
If the value of the variable emaiL is the string 'mine', this creates the SQL statement
SELECT * FROM contacts WHERE email = mine
but in this statement, mine would be interpreted by SQLite as a column name. If you want it to be interpreted as a string, quotes would need to be added:
SELECT * FROM contacts WHERE email = "mine"
However, don't try to adjust the string formatting line, query = f'''...''' to add the quotes, instead use a parameterized statement with ? as a placeholder, like you did for the other SQL statements in your code.
query = 'SELECT * FROM contacts WHERE email = ?'
cur.execute(query, (emaiL,))
See How to use variables in SQL statement in Python? for reasons to do so.
In the query query = f'''SELECT * FROM contacts WHERE last_name = {emaiL}''' is it not supposed to be f'''SELECT * FROM contacts WHERE email = {emaiL}'''?
It's probably because your {emaiL} doesn't have quotes for the email in the query, like this:
f'''SELECT * FROM contacts WHERE email = '{emaiL}' '''
If you print out your current query variable, you'll get SELECT * FROM contacts WHERE email = mine, which isn't valid. You want to get the string SELECT * FROM contacts WHERE email = 'mine'.
How can I put a python variable just after the SELECT. The idea is to create a python function with three arguments where you can choose what you what (here, it's the age) from whom (here, it's Mike and James)
conn = sqlite3.connect('test.s3db')
cur = conn.cursor()
cur.execute('''DROP TABLE IF EXISTS people''')
cur.execute('''CREATE TABLE IF NOT EXISTS people
(id INTEGER,
name TEXT,
surname TEXT,
age INTEGER,
alone INTEGER DEFAULT 0);''')
def add_people(id, name, surname, age, alone=0):
cur.executemany('INSERT INTO people (id, name, surname, age, alone) VALUES (?,?,?,?,?)', [(id, name, surname, age, alone)])
conn.commit()
add_people(1, 'SMITH','James',45)
add_people(2,'JOHNSON','Mike',75)
cur.execute('''SELECT (?) FROM people WHERE surname = (?) OR surname = (?)''', ('age','Mike', 'James'))
print(cur.fetchall())
My code return:
[('age',), ('age',)]
instead of :
[(75,), (45,)]
EDIT : I want that what is selected is a variable and not directly written in the query. My goal is to make a function like this one :
def query(what, who_1, who_2):
cur.executemany('''SELECT (?) FROM people WHERE surname = (?) OR surname = (?)''', (what, who_1, who_2))
return cur.fetchall()
Thank you in advance for your answers !
This takes the data you need as argument of select_data_of
import sqlite3
def add_people(id, name, surname, age, alone=0):
cur.executemany('INSERT INTO people (id, name, surname, age, alone) VALUES (?,?,?,?,?)', [(id, name, surname, age, alone)])
conn.commit()
def select_data_of(names, data="age"):
select = []
for name in names:
cur.execute(f'''SELECT [{data}] FROM people WHERE surname = (?)''', (name, ))
select.append(cur.fetchall()[0])
return select
with sqlite3.connect('test.s3db') as conn:
cur = conn.cursor()
cur.execute('''DROP TABLE IF EXISTS people''')
cur.execute('''CREATE TABLE IF NOT EXISTS people
(id INTEGER,
name TEXT,
surname TEXT,
age INTEGER,
alone INTEGER DEFAULT 0);''')
add_people(2,'JOHNSON','Mike',75)
add_people(1, 'SMITH','James',45)
data = select_data_of(("Mike", "James"), data="age")
print(data)
OUT:
[(75,), (45,)]
I think your select query is wrong because of the 'ages' parameter, this new query will work.
Try
cur.execute("SELECT [age] FROM people WHERE surname = 'Mike' OR surname = 'James")
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 = ?
[]
I am trying to add a feature to my program where a teacher sets homework to users from a class they've made. There is a table for users where each user has a unique UserID, classname, firstname and surname. I am trying to take the userIDs of students who are in a certain class, and insert them into a HomeworkSet table. I am able to retrieve the userIDs successfully, but when I insert them into the HomeworkSet table, the values appear as (for example) ('2a1910e919a84230bfc2a7111160cade',), and I am not sure how I am meant to remove the brackets and apostraphes.
def Class_sethw():
homeworktoset = Homework_To_Set.get()
#print (homeworktoset)
conn = sqlite3.connect('MyComputerScience.db')
c = conn.cursor()
homeworkID = c.execute("SELECT HWID FROM HomeworkInfo WHERE HomeworkName = ?", (homeworktoset, )).fetchone()
print (homeworkID)
c.execute("SELECT UserID FROM users WHERE ClassName = ?", (ClassName_SetHWR, ))
homeworksetlist = c.fetchall()
print (homeworksetlist)
for i in (homeworksetlist):
#x = i
#firstname, lastname = x.split(" ")
c.execute('insert INTO HomeworkSet (HWID, StudentID)VALUES(?,?);', ((homeworkID[0]), str(i)))
conn.commit()
Label(sethw, text = "Homework Set!", fg = "GREEN").place(relx=0.205, rely=0.445, height=34, width=97)
This is the code I have used.
You should change this line:
for i in (homeworksetlist):
to:
for i in homeworksetlist:
I am using the Spyder2 IDE in the python(x,y) package. The below function runs fine in Iron Python, but has errors when I run in the console. I need it to run in the console so that I can use Pyinstaller. The error I get is: "Error binding parameter 0. Probably unsupported type." The line showing the error is the "cur.execute" line. I'm also using Sqlite3 and getting text data from PYQT4 lineEdit fields.
Here is the code:
def update_clients(self):
#Get client id from list
cid = None
try:
cid = self.client_list_id()
except:
QtGui.QMessageBox.warning(self, 'Warning', 'You must first select a client before you update')
if cid:
#Get update items
first = self.lineEdit_c_first.text()
last = self.lineEdit_c_last.text()
add1 = self.lineEdit_c_address1.text()
add2 = self.lineEdit_c_address2.text()
city = self.lineEdit_c_city.text()
state = self.lineEdit_c_state.text()
zipp = self.lineEdit_c_zip.text()
phone = self.lineEdit_c_phone.text()
cell = self.lineEdit_c_phone_cell.text()
off = self.lineEdit_c_phone_office.text()
email = self.lineEdit_c_email.text()
notes = self.textEdit_c_notes.toPlainText()
#Update database
conn = sqlite3.connect('gibbs.db')
cur = conn.cursor()
sql = ("""
UPDATE clients
SET
firstname = ?,
lastname = ?,
address1 = ?,
address2 = ?,
city = ?,
state = ?,
zip = ?,
phone = ?,
officephone = ?,
cell = ?,
email = ?,
notes = ?
WHERE rowid = ?
""")
cur.execute(sql, (first, last, add1, add2, city, state, zipp, phone, off, cell, email, notes, cid,))
conn.commit()
conn.close()
QtGui.QMessageBox.information(self, 'Success', 'Database successfully updated')
Additionally, since the issue is somehow related to data types, here is the code that I used to create the database tables:
import sqlite3
def create_connection():
try:
conn = sqlite3.connect('gibbs.db')
return conn
except:
pass
return None
def create_clients():
try:
conn = create_connection()
print conn
c = conn.cursor()
c.execute("""
CREATE TABLE clients (
id INTEGER PRIMARY KEY,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
firstname TEXT,
lastname TEXT,
address1 TEXT,
address2 TEXT,
city TEXT,
state TEXT,
zip TEXT,
phone TEXT,
officephone TEXT,
cell TEXT,
email TEXT,
notes TEXT
)
""")
conn.close()
except:
print "table already exists"
I added the line print type(first), as suggested by #roganjosh, just before the query. When running the program, the result was different in the two consoles. The Iron Python console outputs: <type 'unicode'> and in Python 2.7 console it is: <class 'PyQt4.QtCore.QString'>.
I solved by adding the str() function when getting my text from the PYQT4 lineEdits. For example:
first = str(self.lineEdit_c_first.text())