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.
Related
I want a login system which relates to a register database I made
I am trying to make a complex query which takes the user input:
Entry(self.root,
textvariable=self.username) ##There is more but I want this to be as minimal as possible
Entry(self.root,
textvariable=self.password,
show="*")
This user input then gets compared with the one in the database.
This is where I am finding it diffucult:
def login(self):
con = sqlite3.connect("register.db") ##The database which I want to open and compare user inputs to
c = con.cursor()
c.execute("SELECT * FROM register")
slist = c.fetchall()
values = [row[0] for row in slist]
values2 = [row[1] for row in slist]
if self.username.get() == values and self.password.get()==values2:
command=self.invcon ##A external thing I want to open if the user enters the data in correctly
else:
messagebox.showerror("Error","Error"parent=self.root)
con.commit()
con.close()
The error which is now happening is instead of opening the new window it moves into the else and pops up with the error box.
Database
The SQL "SELECT username * FROM register" should be "SELECT * FROM register".
Also values and values2 are list, so the comparison between a string (self.username.get() or self.password.get()) and a list will always be False.
However, you don't need to select all records from the table, just select the record with the username and password is enough:
def login(self):
con = sqlite3.connect("register.db") ##The database which I want to open and compare user inputs to
c = con.cursor()
# assume the fields required are 'username' and 'password'
# change them to suit your table definition
c.execute("SELECT 1 FROM register WHERE username = ? AND password = ?", (self.username.get(), self.password.get()))
result = c.fetchone() # get the record if any
if result:
# record found
command=self.invcon ##A external thing I want to open if the user enters the data in correctly
else:
# record not found
messagebox.showerror("Error", parent=self.root)
con.close()
I don't understand all of the errors but when selecting something from a table (in this case 'register') you can either select things by listing them up like:
c.execute("SELECT username, password ... FROM register")
or you simply select everything:
c.execute("SELECT * FROM register")
In this case you did both ("SELECT username * FROM ...") which is why there could be an error.
I did some minor refactoring to some working code. All I did was add 2 functions to clean up how input and it's assignment was handled. I did not change anything about the query_pswd_by_name function but now it doesn't return the password, it returns None. Everything else works perfectly. Any ideas what is going on? Here is the code:
import secrets
import string
import sqlite3
import pyperclip
import optparse
#CREATE PASSWORD OF GIVEN LENGTH
def get_pass(length):
return "".join(secrets.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits + string.punctuation) for x in range(length))
def get_pass_length():
length = int(input("Enter the length of password: "))
password= get_pass(length)
print(password)
pyperclip.copy(password)
print('Password copied to clipboard')
def create_and_store_pwsd():
password = get_pass_length()
name = str(input("Enter name for password: "))
#CREATE DATABASE CONNECTION
conn = sqlite3.connect("managerDB.db")
#CREATE CURSOR OBJECT
c = conn.cursor()
#CREATE TABLE IN DISK FILE BASED DATABASE
c.execute("""CREATE TABLE IF NOT EXISTS password_table (
name TEXT,
pswd TEXT
)""")
#c.execute("DELETE FROM password_table")
c.execute("INSERT INTO password_table (name, pswd) VALUES (?, ?)", (name, password))
#COMMIT CHANGES
conn.commit()
conn.close()
def query_pswd_by_name(name):
conn = sqlite3.connect('managerDB.db')
c = conn.cursor()
query_password = "SELECT pswd FROM password_table WHERE name = ?"
c.execute(query_password,(name,))
result = c.fetchall()
for row in result:
pyperclip.copy(str(row[0]))
print("Password copied to clipboard")
print(str(row[0]))
conn.commit()
conn.close()
def input_name_and_query():
name = input('Name of password you wish to query: ')
query_pswd_by_name(name)
create_and_store_pwsd()
input_name_and_query()```
I mean, at face value, it returns None because you never return anything from the function. You are copying it to the clip board.
A bit more detail would be good. What functions were refactored? What is the output to the console of all your print statements?
As an aside, I'd recommend wrapping the module functionality (last two calls) in an if __name__ == "__main__" block
Here is my code:
def delWorker():
deleteWorker = input('Please type in the surname of the worker you would like to delete. ')
c.execute("DELETE FROM employees WHERE lastName = (?)",
(deleteWorker))
conn.commit()
I am getting error as 'incorrect bindings supplied error'
You want
c.execute("DELETE FROM employees WHERE lastName = (?)", (deleteWorker,))
=> notice the trailing comma after deleteWorker, this is what creates a tuple - The parens are only there for disambiguation, so without the comma what Python sees is:
c.execute("DELETE FROM employees WHERE lastName = (?)", deleteWorker)
so you're actually passing a string when cursor.execute() expects a tuple or list.
I am trying to see whether the type is either a the letter "T" or between number 1-6 for the specific data entry found with name and password.
sql = 'SELECT type FROM table name WHERE name = "{}" AND password = "{}"'.format(username, password)
and then in psedocode i need something like:
if type =< 5:
int()
elif type = "T"
string()
I am using python 2.7
Here is a full script that will query the mysql DB, and use your above-mentioned logic to print the values. I've included the python code as well as the sample database code for this test case. Let me know if you have any questions.
Python
import pymysql
connection = pymysql.connect(user='username', passwd='password',
host='localhost',
database='database')
cursor = connection.cursor()
NAME = 'Person_A'
PASSWORD = 'Password_A'
query = ("SELECT * FROM My_TABLE WHERE NAME = '%(1)s' AND PASSWORD = '%(2)s';" % {"1" : NAME, "2" : PASSWORD})
cursor.execute(query)
for item in cursor:
type = item[0]
if type.isdigit():
if int(type) <6:
print('Type is a number less than 6')
else:
print('Type is a number but not less than 6')
else:
if type == 'T':
print('Type is a string == T')
else:
print('Type is a string but not the letter T')
MYSQL
CREATE TABLE MY_TABLE (TYPE VARCHAR(255), NAME VARCHAR(255), PASSWORD VARCHAR(255));
INSERT INTO MY_TABLE VALUES ('T','Person_A','Password_A'),('4','Person_A','Password_A'),('7','Person_B','Password_B'),('t','Person_C','Password_C');
New to Python and Databases
I have a database table set up with a column of usernames. I want the user to be able to search through the table via a raw_input and only return the values which are associated with that user name.
E.g. user searches for Bill and it only displays Bill's records ordered by a specified column
This is what I have so far but its obviously VERY wrong, hope someone can help:
def find_me(db, column_name):
db = sqlite3.connect(db)
cursor = db.cursor()
name = raw_input("Please enter your username: ")
cursor.execute("SELECT name FROM username WHERE name=?", (name,))
cursor.execute("SELECT * FROM username ORDER BY "+column_name+" ASC")
name = cursor.fetchone()
next = cursor.fetchone()
Thank you in advance
You want to make the query similar to the following:
cursor.execute("SELECT name FROM username WHERE name=?", (name,))
This uses query parameters, so it's correctly escaped for the data provided. Then just adapt this to SELECT * and whatever else you want from the result.
Try working with this:
name = raw_input("Please enter your username: ")
query = "SELECT * FROM username WHERE name=? ORDER BY {0}".format(column_name)
cursor.execute(query, (name,))
for row in cursor:
print row