Username is a variable that is drawn from an Entrybox using tkinter. I need for dbsalt to return the outcome of the cursor1.execute query as a string, but it returns "none" or presents a traceback that states "NoneType has no attribute getitem". I do not understand what is incorrect.
def login_verification(self):
sql = ("SELECT salt FROM User WHERE username = %s")
username = self.KUEntry.get()
print username
cursor1.execute(sql, username)
dbsalt = cursor1.fetchone() [0]
print dbsalt
sql2 = ("SELECT PashHash FROM User WHERE username = %s")
cursor2.execute(sql2, username)
dbhash = cursor2.fetchone() [0]
print dbhash
test = hashlib.sha512(username + dbsalt).hexdigest()
print test
if test == dbhash:
self.intro_screen
else:
print "incorrect password"
You didn't call execute method, but assigned to it. Call it using cursor.execute(..):
And you should use ' to quote the string.
username = self.KUEntry.get()
cursor1.execute("SELECT salt FROM User WHERE username = '%s'" % username)
dbsalt = str(cursor1.fetchone())
print dbsalt
BTW, it is better to use parameter passing style than manually formatting string to prevent SQL injection.
cursor1.execute("SELECT salt FROM User WHERE username = %s", [username])
Related
Im making a login system as a data base Im using SQLite.
def loginfunction(self):
user = self.emailfield.text()
password = self.passwordfield.text()
if len(user)==0 or len(password)==0:
self.error.setText("Please input all fields.")
else:
conn = sqlite3.connect("shop_data.db")
cur = conn.cursor()
query = 'SELECT password FROM login_info WHERE username =\''+user+"\'"
cur.execute(query)
result_pass = cur.fetchone()[0]
if result_pass == password:
print("Successfully logged in.")
self.error.setText("")
else:
self.error.setText("Invalid username or password")
When I run it if the password does not match with the username from the data base it works but if I type a wrong username the app closes and prints out this
main.py", line 38, in loginfunction
result_pass = cur.fetchone()[0]
TypeError: 'NoneType' object is not subscriptable
Here is what SQLite log says + what the data base looks like data base
fetchone does
Fetches the next row of a query result set, returning a single
sequence, or None when no more data is available.
For any
'SELECT password FROM login_info WHERE username =\''+user+"\'"
there is not matching row in data if user provided username not present in username column. You should do something like
query_result = cur.fetchone()
if result_pass is None:
print("Username with given name is not known")
# action to undertake in such case
result_pass = query_result[0]
then continue as earlier
This question already has answers here:
MySQL/Python -> Wrong Syntax for Placeholder in Statements?
(1 answer)
Why can't replace placeholder with format function in pymysql?
(3 answers)
Closed 2 years ago.
Why does the fetchone() return None when onLogin() is called, even though the database has a row with a value?
When I use the same query in the sql database it returns the correct value.
Using fetchall() and using a for loop with it returns nothing on the terminal.
import mysql.connector
#SQL CONNECTION
db = mysql.connector.connect(
host="localhost",
user="root",
password="",
database="python"
)
cursor = db.cursor(buffered=True)
#main
def onStart():
global username
print("Enter a username to continue")
username = input()
#Checking the database for the username
query = "SELECT username FROM userdata"
cursor.execute(query)
result = cursor.fetchall()
for x in result:
if x == (username,):
onLogin()
else:
print("Error Occurred!")
def onLogin():
print("Enter a password")
password = input()
#comparing pwds
query = "SELECT password FROM userdata WHERE username = '%s'"
cursor.execute(query, username)
result = cursor.fetchone()
print(result)
onStart()
As deceze said, you shouldn't quote the '%s' placeholder in the prepared query.
In addition, you should avoid doing getting every single user in your database just to figure out if this one exists - and while you're at it, you can get the password in the same query and just compare it in your program. (Naturally in a real-life situation you'd use a password derivation function and not store cleartext passwords in the database.)
import mysql.connector
# SQL CONNECTION
db = mysql.connector.connect(
host="localhost", user="root", password="", database="python"
)
cursor = db.cursor(buffered=True)
def authenticate():
username = input("Enter a username to continue")
cursor.execute(
"SELECT username, password FROM userdata WHERE username = %s LIMIT 1",
(username,),
)
result = cursor.fetchone()
if not result:
print("No such user.")
return None
username, correct_password = result
password = input("Enter a password")
if password == correct_password:
print("Access granted!")
return username
username = authenticate()
# If `username` is none, authentication failed
I created a database called finance.db and it contains a table named 'test'. The table takes 5 parameters including 'user' and 'password'. A user is already inserted into the table.
I would like the user to be able to log in by providing their username and password and matching that against the database table 'test'. If the table contains the correct username and password it allows the user to log in.
Here is how I imagine it would work:
import sqlite3
user_name = input('Enter username: ')
user_password = input('Enter password:')
def login_details(username, password):
connection = sqlite3.connect('finance.db')
cursor = connection.cursor()
cursor.execute('SELECT * FROM test')
check = cursor.fetchall()
for i in check:
if username and password in check:
print('works')
else:
print('not in db')
login_details(username=user_name, password=user_password)
Unfortunatelly it always returns 'not in db', even if correct details are inserted. I'm not sure what I am missing, but I suspect that my if statement is simply incorrect, but it does not result in a syntax or other error.
UPDATE:
I solved the problem by extracting the information that I require from a tuple and then storing its value in a variable. Here is what I changed:
for i in check:
user_name_input = i[1]
user_pass_input = i[2]
if user_name_input != username and user_pass_input != password:
print('not in db')
else:
print('in db')
In this part of code
for i in check:
if username and password in check
I suppose that check is a list of tuples that represents all the query matched rows in the table. So i is a tuple and you should compare your variables with the specific positions of the tuple which correspond to the fields username and password. Perhaps something like that:
for i in check:
if username == i[0] and password == i[1]
I have imported uuid and used it to randomly generate a 32 digit UserID, and at first it would work fine and register the user, but when I attempted to try and first check the database incase the UserID has already been used, I get a binding error, and can't figure out whats wrong with it.
var_usertype = ("Teacher")
Firstname = var_FName.get()
Surname = var_SName.get()
Password = var_password1.get()
username = Firstname[0:3] + Surname
conn = sqlite3.connect('MyComputerScience.db')
c = conn.cursor()
UserID = str(uuid.uuid4()).replace('-','')
var_insert = (UserID, Firstname, Surname, Password, username, var_usertype)
c.execute("SELECT * FROM users WHERE UserID = ?", (UserID))
data = c.fetchall()
if len(data) == 0:
c.execute('insert INTO users (UserID, FName, SName, password, username, userType)VALUES(?,?,?,?,?,?);', var_insert)
Label(screen2, text = "Successfully registered! Your username to log in is "+username+"", fg = "GREEN", font = "Calibri").pack()
Main.login()
c.execute("SELECT * FROM users WHERE UserID = ?", (UserID))
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 32 supplied.
c.execute("SELECT * FROM users WHERE UserID = ?", (UserID))
This is a very common beginner mistake. The second argument is supposed to be a tuple, list or other similar thing. In this case, you're passing it a string, and each character is treated as an individual value that should be bound.
You want:
c.execute("SELECT * FROM users WHERE UserID = ?", (UserID,))
Note the trailing comma to make the argument a one-element tuple.
I have a database in mysql, and I'm working in a app in QT4, I'm using Mysqldb connector, I'm already successfully connected to the database, but when I'm querying the table t_usuarios I don't know how to eval it. Can you help me? Thanks in advance.
Part of my code:
def chequeouser(self):
passwdcheck = str(txt_password.text())
usuariover = str(txt_usuario.text())
# datosLogin = "SELECT * FROM t_usuarios WHERE id_usuario = 'usuario' AND pasword = 'password'
cursor = dbase.cursor()
cursor.execute("SELECT id_usuario, password FROM t_usuarios WHERE id_usuario = %s AND password = %s", (usuariover, passwdcheck))
checar = cursor.fetchone()
Thanks for the user who answer me ... I do it, but with some modification as follow ..
passwdcheck = str(txt_password.text())
usuariocheck = str(txt_usuario.text())
# datosLogin = "SELECT * FROM t_usuarios WHERE id_usuario = 'usuario' AND pasword = 'password'
cursor = dbase.cursor()
cursor.execute("SELECT id_usuario, password FROM t_usuarios WHERE id_usuario = %s AND password = %s", (usuariocheck, passwdcheck))
row = cursor.fetchone()
if row == None:
print "no data:"+ usuariocheck
return
if row[1] == passwdcheck:
print "user and password combination is correct" +usuariocheck
else :
print "your input is incorrect"
I'm thinking do this in answer but I not sure if this is correct or not.
fetchone() returns a row of data. The first item is row[0], 2nd item is row[1], etc.
Example:
def chequeouser(self):
passwdcheck = str(txt_password.text())
usuariover = str(txt_usuario.text())
# datosLogin = "SELECT * FROM t_usuarios WHERE id_usuario = 'usuario' AND pasword = 'password'
cursor = dbase.cursor()
cursor.execute("SELECT id_usuario, password FROM t_usuarios WHERE id_usuario = %s AND password = %s", (usuariover, passwdcheck))
row = cursor.fetchone()
if not row:
print "no rows!"
return
if passwdcheck == row[1]:
print 'MATCH for user', row[0]
else:
print 'uhoh'