我想检查用户名是否存在于表中。当我从表中选择所有内容时,代码正在工作,但是当我仅尝试使用用户名时出现错误。我得到的错误是
调用中的文件“ \ Python \ Python37 \ lib \ tkinter__init __。py”,行1705 返回self.func(* args)
在创建中,文件/Calculator_calorie/login_register.py”,第89行
login_backend.insert(self.namere_text.get(),self.passwordr1e_text.get())
文件\ Calculator_calorie \ login_backend.py”,插入第18行
if cur.execute('SELECT name FROM user WHERE name = ?',(name)):
sqlite3.ProgrammingError:提供的绑定数不正确。当前语句使用1,并且提供了4。
import sqlite3
from tkinter import *
from tkinter import messagebox
from user import user
def connect():
conn=sqlite3.connect("login.db")
cur=conn.cursor()
cur.execute("CREATE TABLE if NOT exists user(name text,password text)")
conn.commit()
conn.close()
def insert(name,password):
conn=sqlite3.connect('login.db')
cur = conn.cursor()
if cur.execute('SELECT * FROM user WHERE name = ?', (name)):
if cur.fetchone():
messagebox.showinfo('Error', 'User already exist')
else:
cur.execute('INSERT INTO user VALUES(?,?)', (name, password))
messagebox.showinfo('Register', 'Entry sucess')
conn.commit()
conn.close()
def create(self):
if self.passwordr1e.get() != self.passwordr2e.get():
messagebox.showinfo('error','Passwords do not match')
elif len(self.namere.get()) == 0:
messagebox.showinfo('error', 'Name field is empty')
elif len(self.passwordr1e.get()) == 0:
messagebox.showinfo('error', 'PASSWORD field is empty')
else:
login_backend.insert(self.namere_text.get(),self.passwordr1e_text.get())
答案 0 :(得分:1)
As Michael commented,要让Python识别具有单个值的元组,它需要在末尾加逗号。 (name,)
不是(name)
。参见W3Schools Python Tuples。
if cur.execute('SELECT name FROM user WHERE name = ?',(name,)):
请注意,如果您只是检查行是否存在,请select 1
来节省时间。
但是,有一种更安全,更快捷的方法。
As Chris commented,检查用户并插入用户是否不包含race condition。如果两个进程试图同时创建相同的用户,他们都会以为这两个用户都不存在,并且都插入会导致重复。
Proc 1 Proc 2
t SELECT * FROM user WHERE name = ?
i SELECT * FROM user WHERE name = ?
m 0 records found
e 0 records found
| INSERT INTO user VALUES(?,?)
v INSERT INTO user VALUES(?,?)
相反,设置一个unique constraint,执行insert
,然后捕获唯一的错误。
CREATE TABLE if NOT exists user(
name text unique not null,
password text not null
)
def insert(name,password):
conn=sqlite3.connect('login.db')
cur = conn.cursor()
try:
cur.execute('INSERT INTO user VALUES(?,?)', (name, password))
messagebox.showinfo('Register', 'Entry sucess')
except sqlite3.IntegrityError as e:
if re.match(r'UNIQUE constraint failed', e.args[0]):
messagebox.showinfo('Error', 'User already exist')
else:
raise e
conn.commit()
conn.close()
对存在性进行检查并在单个查询中插入称为“原子”,因为这两个部分无法分开。
手工编写SQL对学习很有帮助,但对于生产工作,请使用诸如SQL Alchemy之类的框架。
将密码存储为纯文本是不安全的。 Use a password hashing library such as bcrypt并继续阅读password hashing。
为每个查询重新连接到数据库效率很低。连接一次并保持连接打开。