I have a Python function that is supposed to check if a value is present in my SQLite table. I have a table named Users and it stores the value userid which is a random string of integers and letters. For example, a userid would look like this f75fsf3dbg9g. In def chk(): the user inputs their uid then the uid_chk(): function is called to check if the uid value equals one of the userid being stored in the table.
My issue is in the cur.execute(query,tagValue) line in the uid_chk() function. It throws the Error: sqlite3.programmingError: Incorrect number of bindings supplied. The current statement uses 1
Nothing is being returned from the function uid_chk() just prints out None
For reference when the table Users is printed out it looks like this: [('hk12lkj14vh',),('bn465i32',),('d8j4k0fl',),('k4i9b3k0s2',),('rk2nk50sp26',),('rk3ji9al23',),]
import RPi.GPIO as GPIO
import sqlite3 as sql
from mfrc522 import SimpleMFRC522
reader = SimpleMFRC522()
def chk():
print("Scan tag")
try:
uid_tag = reader.read()
#If the user has inputed value (uid)
if uid_tag :
#Var for inputed userid
tagValue = uid_tag[1]
print(tagValue)
uid_chk(tagValue)
return tagValue
GPIO.cleanup()
except ValueError:
print('Something went wrong')
def uid_chk(tagValue):
Database = sql.connect('test.db')
# cursor
cur = Database.cursor()
# Check if the tagValue maches a value in the userid column of sqlite DB
query = 'SELECT userid FROM Users WHERE userid = ?'
cur.execute(query, tagValue)
row_returned = cur.fetchone()
print(row_returned)
if row_returned == tagValue:
print('User Verified')
else:
print('Something is Wrong')
Database.close()
chk()
Related
Im in the process of creating a website with python flask and html. I want it to have a register, login, edit, delete, and home page. I want to store the users login data in an sqlite database that can then be called to veify the login of the user. in order to have different users have the same username and/or password, I need to give each user a unique ID. I use this ID in the url, and I want the user to be able to use this ID for other things in the website. because of this, when a new user is added I need to give them a random (unique) ID (probably 8 digits). I saw a bunch of stuff about AUTO INCRAMENT being random, but I didnt understand it very much, and I tried it, and it gave me consecutive numbers (which is not what I want) I also tried RANDOM() and RAND() but they both threw syntax errors. can anyone tell me how to generate an sqlite column for an random unique 8 digit ID?
here's what I have:
schema.sql
DROP TABLE IF EXISTS users;
CREATE TABLE users (
id INTEGER PRIMARY KEY --insert random generator here,
username TEXT NOT NULL,
password1 TEXT NOT NULL,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
heres the python that runs the schema:
init_db.py
import sqlite3
connection = sqlite3.connect('database.db')
with open('schema.sql') as f:
connection.executescript(f.read())
cur = connection.cursor()
cur.execute("INSERT INTO users (username, password1) VALUES (?, ?)",
('user1', 'pass1')
)
cur.execute("INSERT INTO users (username, password1) VALUES (?, ?)",
('user2', 'pass2')
)
connection.commit()
connection.close()
thanks in advance for any help
okay.
Ive fixed this by generating a random number in the python code. when a user registers, I take their username and password, then generate a random number between 10000000 and 99999999. then I check if its in the database already, and if so, generate another one, until I generate a unique number. then I add username, password and ID to the database at the same time.
heres what I have now
(disclaimer: i am only showing the relevant code, so some of it might not make sense)
CREATE TABLE users (
id INTEGER,
username TEXT NOT NULL,
password1 TEXT NOT NULL,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
the init_db.py is the same,
heres the python:
from flask import Flask, render_template, url_for, request, flash, redirect, abort#imports
import sqlite3
import random
app = Flask(__name__)
def get_db_connection():
conn = sqlite3.connect('database.db')
conn.row_factory = sqlite3.Row
return conn
def get_username(usernamex):#def and pass usernamex
validated_uname = False#reset progress variable
conn = get_db_connection()#connect to database
cur = conn.cursor()#create a cursor
try:
cur.execute('SELECT * FROM users WHERE username = ?',(usernamex,))#select the row in the users table where username == the usernamex variable
uname = cur.fetchone()[1]#uname = the second column of that row
validated_uname = True#update progress variable
except:#if the above failed: (most likely because usernamex was not in the database):
validated_uname = False#reset progress variable
if validated_uname == True:#if the try function passed:
return(uname)#update uname and send it back
conn.commit()#commit and close database
conn.close()
def get_password1(password1x):#def and pass password1x
validated_upass = False#reset progress variable
conn = get_db_connection()#connect to database
cur = conn.cursor()#create a cursor
try:
cur.execute('SELECT * FROM users WHERE password1 = ?',(password1x,))#select the row in the users table where password1 == the password1x variable
upass = cur.fetchone()[2]#upass = the third column of that row
validated_upass = True#update progress variable
except:
validated_upass = False#reset progress variable
if validated_upass == True:#if the try function passed:
return(upass)#update upass and send it back
conn.commit()#commit and close database
conn.close()
app.config['SECRET_KEY'] = '013ecbdd4aae3899c7feed1bf36dee4e'#secret key
#app.route("/register", methods=('GET', 'POST'))#url, and pass the get and post vaiables to make forms
def register():
if request.method == 'POST':#when request method is post in the html page: #(after they press submit)
usernamex = request.form['username']#take the username entered from html
password1x = request.form['password1']#same for pass1 and pass2
password2x = request.form['password2']
if not usernamex:#if nothing was entered for username:
flash('Username is required!')#error message
elif not password1x:#if nothing was entered for pass1:
flash('Password is required!')#error message
elif not password2x:#if nothing was entered for pass2:
flash('Valdiated password is required!')#error message
elif password1x != password2x:# if pass1 and pass2 dont match:
flash('Passwords do not match!')#error message
else:#otherwise
conn = get_db_connection()#connect to database
cur = conn.cursor()#create cursor
loop = True
while loop == True:
rand_id = random.randint(10000000, 99999999)#generate random number (8 digits)
try:
cur.execute('SELECT * FROM users where id = ?',(rand_id,))#select the row in the users table where id == the rand_id variable
r_id = cur.fetchone()[0]#r_id = the first column from that row ## this is just here to throw the error
except:
cur.execute('INSERT INTO users (id, username, password1) VALUES (?, ?, ?)',(rand_id, usernamex, password1x))#make a new row, and put in ID, username and password1 in their respective places
loop = False#break the loop
conn.commit()#commit and close database
conn.close()
id = rand_id#for the home url
#id = home_id(usernamex, password1x)#id = [call the home_id function {pass usernamex and password1x}]
return redirect(url_for('home', id=id))#go to the home page and pass id for the url
return render_template('register.html', title = 'Register')#render the template from register.html
thanks for everyones help :)
I wrote a code to delete some users from the database, but it said Incorrect number of bindings supplied. The current statement uses 1, and there are 4 supplied.
def delete_user(self, user_id):
stmt = "DELETE FROM user WHERE user_id = (?)"
args = user_id
try:
self.conn.executemany(stmt, (args,))
self.conn.commit()
except sqlite3.Error as e:
logging.error(str(e))
My part main code:
deleted_user = []
deleted_user.append(1384995383)
deleted_user.append(1667596031)
deleted_user.append(1332658866)
deleted_user.append(1295962235)
print(deleted_user)
db.delete_user(deleted_user)
I found this answer: sqlite3: Incorrect number of bindings supplied. The current statement uses 1, and there are 5 supplied
I try to use tuple(user_id) to convert it to a tuple, but the result was not I'm except
Origin deleted_user list:
[1384995383, 1667596031, 1332658866, 1295962235]
After tuple(user_id) result:
(1384995383, 1667596031, 1332658866, 1295962235)
What I Expectation:
[(1384995383,), (1667596031,), (1332658866,), (1295962235,)]
I tried searching, but I couldn't get the answers I wanted :(
def delete_user_ids(self, user_ids):
stmt = "DELETE FROM user WHERE user_id = (?)"
try:
self.conn.executemany(stmt, user_ids)
# ^^^^^^^^
user_ids = []
user_ids.append((1384995383,))
user_ids.append((1667596031,))
user_ids.append((1332658866,))
user_ids.append((1295962235,))
delete_user_ids(user_ids)
Try this:
deleted_user.append((1384995383,))
I have a SQL database that displays a varbinary (max) like this 0x9406920691068F... I want to import it to python pycharm to get the same exact type of data.
However, it shows something like this instead
[b'\x94\x06\x92\x06\x91\x06\x8f\x06\x8d..
how do I copy the same numbers to python? I am a beginner in python, please help.
I copied the code from previous post and it didn't work
import pyodbc
def hexToString(binaryString):
try:
hashString = ["{0:0>2}".format(hex(b)[2:].upper()) for b in binaryString]
return '0x' + "".join(hashString)
except:
return binaryString
query = """ select P from Access.table """
conn_str = (
**** private database details # I don't copy on the page
)
cnxn = pyodbc.connect(conn_str)
cnxn.add_output_converter(pyodbc.SQL_BINARY, hexToString)
cursor = cnxn.cursor()
try:
cursor.execute(query)
row = cursor.fetchone()
except MySQLdb.error as err:
print(err)
else:
while row is not None:
print(row)
row = cursor.fetchone()
If the column return type is varbinary(max) then you need to add the output converter function to handle SQL_VARBINARY, not SQL_BINARY
cnxn.add_output_converter(pyodbc.SQL_VARBINARY, converter_function_name)
I have created the following functions to create a table call user.
import sqlite3
from datetime import datetime
def create_connection(db_file):
try:
connection = sqlite3.connect(db_file)
return connection
except sqlite3.Error as e:
print(e)
return None
def create_table(connection, sql_table):
cursor = connection.cursor()
with connection:
try:
cursor.execute(sql_table)
except sqlite3.Error as e:
print(e)
def insert_user(connection, date, username):
cursor = connection.cursor()
with connection:
cursor.execute("INSERT INTO user VALUES(?,?)",(date, username))
database = "test.db"
user_table = """ CREATE TABLE IF NOT EXISTS user (
date TEXT NOT NULL,
username TEXT NOT NULL
); """
conn = create_connection(database)
create_table(conn, user_table)
date = datetime.now().strftime('%Y-%m-%d')
username = 'user1'
insert_user(conn, date, username)
I would like to make the function insert_user more general. I would like to be able to pass user into this function and not have to explicitly write user in
cursor.execute("INSERT INTO user VALUES(?,?)",(date, username))
Similarly, I would like to avoid explicitly writing user in
user_table = """ CREATE TABLE IF NOT EXISTS user (
Rather I would like to have a variable having the value of user and passing that variable into this statement.
How should I amend my code? Thanks.
I'm working on an IRC bot, forked from a modular bot called Skybot.
There are two other modules that make use of the sqlite3 database by default; they have both been removed and their tables dropped, so I know that the issue is somewhere in what I'm doing.
I only call 3 db.execute() statements in the whole thing and they're all immediately committed. This thing isn't getting hammered with queries either, but the lock remains.
Relevant code:
def db_init(db):
db.execute("create table if not exists searches"
"(search_string UNIQUE PRIMARY KEY,link)")
db.commit()
return db
def get_link(db, inp):
row = db.execute("select link from searches where"
" search_string=lower(?) limit 1",
(inp.lower(),)).fetchone()
db.commit()
return row
def store_link(db, stub, search):
db.execute("insert into searches (search_string, link) VALUES (?, ?)", (search.lower(), stub))
db.commit()
return stub
If the script only has to touch db_init() and get_link() it breezes through, but if it needs to call store_link() while the database is unlocked it will do the insert, but doesn't seem to be committing it in a way that future calls to get_link() can read it until the bot restarts.
The bot's db.py:
import os
import sqlite3
def get_db_connection(conn, name=''):
"returns an sqlite3 connection to a persistent database"
if not name:
name = '%s.%s.db' % (conn.nick, conn.server)
filename = os.path.join(bot.persist_dir, name)
return sqlite3.connect(filename, isolation_level=None)
bot.get_db_connection = get_db_connection
I did adjust the isolation_level myself, that was originally timeout=10. I am fairly stumped.
EDIT: The usages of get_db_connection():
main.py (main loop):
def run(func, input):
args = func._args
if 'inp' not in input:
input.inp = input.paraml
if args:
if 'db' in args and 'db' not in input:
input.db = get_db_connection(input.conn)
if 'input' in args:
input.input = input
if 0 in args:
out = func(input.inp, **input)
else:
kw = dict((key, input[key]) for key in args if key in input)
out = func(input.inp, **kw)
else:
out = func(input.inp)
if out is not None:
input.reply(unicode(out))
...
def start(self):
uses_db = 'db' in self.func._args
db_conns = {}
while True:
input = self.input_queue.get()
if input == StopIteration:
break
if uses_db:
db = db_conns.get(input.conn)
if db is None:
db = bot.get_db_connection(input.conn)
db_conns[input.conn] = db
input.db = db
try:
run(self.func, input)
except:
traceback.print_exc()
Send conn in your functions, along with db, as mentioned. If you wrote the code yourself, you'll know where the database actually is. Conventionally you would do something like:
db = sqlite3.connect('database.db')
conn = db.cursor()
Then for general usage:
db.execute("...")
conn.commit()
Hence, in your case:
def db_init(conn,db):
db.execute("create table if not exists searches"
"(search_string UNIQUE PRIMARY KEY,link)")
conn.commit()
return db
def get_link(conn,db, inp):
row = db.execute("select link from searches where"
" search_string=lower(?) limit 1",
(inp.lower(),)).fetchone()
conn.commit()
return row
def store_link(conn,db, stub, search):
db.execute("insert into searches (search_string, link) VALUES (?, ?)", (search.lower(), stub))
conn.commit()
return stub
On the basis that you have set the isolation_level to automatic updates:
sqlite3.connect(filename, isolation_level=None)
There is no need whatsoever for the commit statements in your code
Edit:
Wrap your execute statements in try statements, so that you at least have a chance of finding out what is going on i.e.
import sqlite3
def get_db(name=""):
if not name:
name = "db1.db"
return sqlite3.connect(name, isolation_level=None)
connection = get_db()
cur = connection.cursor()
try:
cur.execute("create table if not exists searches"
"(search_string UNIQUE PRIMARY KEY,link)")
except sqlite3.Error as e:
print 'Searches create Error '+str(e)
try:
cur.execute("insert into searches (search_string, link) VALUES (?, ?)", ("my search", "other"))
except sqlite3.Error as e:
print 'Searches insert Error '+str(e)
cur.execute("select link from searches where search_string=? limit 1", ["my search"])
s_data = cur.fetchone()
print 'Result:', s_data