Taking value from column in one sqlite3 table and inserting into another - python

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:

Related

Why does the searching of an item in my sqlite table, using python, only work when the data is a number saved as text?

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 "get" the data from a sqlite3 database and store them as variables?

I am trying to query whether the staff ID and password are correct. The query works, however I want to get the fname and lname data from the database and print certain fields. It seems as though the row[fname] and row[lname] doesn't work... is there another way to do this? I keeps saying fname is not defined.
import sqlite3
connection = sqlite3.connect('shop.db')
cursor = connection.cursor()
create_table = '''
CREATE TABLE IF NOT EXISTS employee (
staff_ID INTEGER PRIMARY KEY,
password CHAR(4),
fname VARCHAR(20),
lname VARCHAR(30));'''
cursor.execute(create_table)
staffid = input('staff id: ')
password = input('password: ')
cursor.execute('SELECT * FROM employee WHERE staff_ID=? AND password=?', [staffid, password])
row = cursor.fetchone()
if row != None:
print(row[fname]+' '+row[lname])
You may insert any values into this table, I just didn't want the code to look too bulky... Thanks!

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()

Performing an SQL query for each item in a tuple

I am new to Python and am hoping someone can help me figure out how to perform an SQL query on each item in a tuple using Python.
I have a SQL Express server that contains a number of databases for a badge reader system. What I am trying to do is pull the user id's that have scanned into a particular reader, then use those id's to get the actual user names.
Currently, I am able run the query that pulls the user id's and run a query on the other table using just one id. What want to be able to do, and seem to be having an issue figuring out, is running that second query on every user id in the tuple that is created from the first query. Below is the code for the two functions I am currently using.
def get_id():
global cardholder
global cur
cur.execute("SELECT user_id FROM db.table WHERE badgereaderid = 'badgereader1'")
cardholder = []
rows = cur.fetchall()
for row in rows:
if row == None:
break
cardholder.append(row[0])
print(cardholder)
def get_name():
global cardholder
global user
global cur
cur.execute("SELECT FirstName, LastName FROM db.table WHERE user_id= '%s'" % cardholder)
while 1:
row = cur.fetchone()
if row == None:
break
user = row[0] + row[1]
Two possible options
Repeated queries in Python
for user_id in cardholder:
cur.execute("SELECT FirstName, LastName FROM db.table WHERE user_id= '%s'" % user_id)
But why not just pull all the data in the first query?
cur.execute("SELECT a.user_id, b.FirstName, b.LastName FROM db.table1 a left join bd.table2 b on a.user_id = b.user_id WHERE a.badgereaderid = 'badgereader1'")
or, use triple quotes to allow multi-line strings and make the SQL command easier to understand
cur.execute("""SELECT
a.user_id,
b.FirstName,
b.LastName
FROM db.table1 a
left join db.table2 b
on a.user_id = b.user_id
WHERE a.badgereaderid = 'badgereader1'""")
A good practice in Python is to define the data collections outside the function if you intend to use them later on in your code
Try this code:
cardholder_names = []
#pass the cardholder as a param to the function
def get_name(cardholder):
#cur is already defined as a global param, no need to do it twice
cur.execute("SELECT FirstName, LastName FROM db.table WHERE user_id='{0}'".format(cardholder))
return cur.fetchone()
#now use the for loop to iterate over all the cardholders
for holder in cardholders:
cardholder_name = get_name(holder)
cardholder_names.append( {"name" : cardholder_name[0], "surname" : cardholder_name[1]})

Categories

Resources