如何在Python操作的MySQL考勤数据库中实现签退动作?
RFID签到签退系统签退逻辑实现方案
我正在做一个学校项目,通过RFID读卡器读取RFID卡片,将签到(check_in)和签退(check_out)时间存储到MySQL数据库中。目前已实现签到功能,但无法完成“查询用户当日已有记录并自动添加签退动作”的逻辑。
数据库表结构
create table attendance_check( id INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE, date_id DATE NOT NULL DEFAULT CURRENT_DATE, user_id INT UNSIGNED NOT NULL, name VARCHAR(255) NOT NULL, clock_id TIME NOT NULL DEFAULT CURRENT_TIME, Action VARCHAR(255) NOT NULL, PRIMARY KEY ( id ) );
Action字段用于记录"in"(签到)和"out"(签退),date_id默认取当前日期,clock_id默认取当前时间。
当前实现代码
while True: lcd.clear() lcd.message('Place Card to\nrecord attendance') id, text = reader.read() cursor.execute("Select id, name FROM users WHERE rfid_uid="+str(id)) result = cursor.fetchone() lcd.clear() name = result[1] number = result [0] action1 = "in" action2 = "out" if cursor.rowcount >= 1: lcd.message("Welcome " + name) add = ("INSERT INTO attendance_check (user_id, name, Action) VALUES (%s, %s, %s)") date = (numar, nume, action1) # 注:此处变量名应为number和name,属于笔误 cursor.execute(add, date) db.commit() else: lcd.message("User does not exist.") time.sleep(2)
签退逻辑实现方案
核心解决思路是:每次读取RFID后,先查询用户当日最新的操作状态,如果是"in"则插入"out"记录,如果是"out"或无当日记录则插入"in"记录。修改后的代码如下:
import time # 假设reader、cursor、db、lcd已完成初始化 while True: lcd.clear() lcd.message('Place Card to\nrecord attendance') id, text = reader.read() # 1. 查询用户信息 cursor.execute("SELECT id, name FROM users WHERE rfid_uid = %s", (str(id),)) result = cursor.fetchone() lcd.clear() if not result: lcd.message("User does not exist.") time.sleep(2) continue user_id = result[0] user_name = result[1] # 2. 查询用户当日最新的签到记录 cursor.execute(""" SELECT Action FROM attendance_check WHERE user_id = %s AND date_id = CURRENT_DATE ORDER BY clock_id DESC LIMIT 1 """, (user_id,)) latest_action = cursor.fetchone() # 3. 判断要执行的动作 if not latest_action or latest_action[0] == "out": current_action = "in" lcd.message(f"Welcome {user_name}\nChecked In") else: current_action = "out" lcd.message(f"Goodbye {user_name}\nChecked Out") # 4. 插入新的记录 insert_sql = """ INSERT INTO attendance_check (user_id, name, Action) VALUES (%s, %s, %s) """ cursor.execute(insert_sql, (user_id, user_name, current_action)) db.commit() time.sleep(2)
关键修改说明
- 用参数化查询替换字符串拼接,避免SQL注入风险(原代码存在注入隐患)
- 新增当日记录查询逻辑:按
clock_id倒序取最新一条记录,精准判断用户当前状态 - 修正原代码中的变量名笔误
- 根据状态动态设置动作,并给出对应的LCD提示
内容的提问来源于stack exchange,提问作者user21192515
相关产品推荐
相关产品推荐

