利用python模拟sql语句对员工表格进行增删改查
本文主要给大家介绍了关于python模拟sql语句对员工表格进行增删改查的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍:
具体需求:
员工信息表程序,实现增删改查操作:
可进行模糊查询,语法支持下面3种:
selectname,agefromstaff_datawhereage>22 多个查询参数name,age用','分割
select*fromstaff_datawheredept=人事
select*fromstaff_datawhereenroll_datelike2013
查到的信息,打印后,最后面还要显示查到的条数
可创建新员工纪录,以phone做唯一键,phone存在即提示,staff_id需自增,添加多个记录record1/record2中间用'/'分割
insertintostaff_datavaluesrecord1/record2
可删除指定员工信息纪录,输入员工id,即可删除
deletefromstaff_datawherestaff_id>=5andstaff_id<=10
可修改员工信息,语法如下:
updatestaff_tablesetdept=Market,phone=13566677787 wheredept=运维 多个set值用','分割
使用re模块,os模块,充分使用函数精简代码,熟练使用str.split()来解析格式化字符串
由于,sql命令中的几个关键字符串有一定规律,只出现一次,并且有顺序!!!
按照key_lis=['select','insert','delete','update','from','into','set','values','where','limit']的元素顺序分割sql.
分割元素作为sql_dic字典的key放进字典中.分割后的列表为b,如果len(b)>1,说明sql字符串中含有分割元素,同时b[0]对应上一个分割元素的值,b[-1]为下一次分割对象!
这样不断迭代直到把sql按出现的所有分割元素分割完毕,但注意这里每次循环都是先分割后赋值!!!当前分割元素比如'select'对应的值,需要等到下一个分割元素
比如'from'执行分割后的列表b,其中b[0]的值才会赋值给sql_dic['select'],所以最后一个分割元素的值,不能通过上述循环来完成,必须先处理可能是最后一个分割元素,再正常循环!!
在这sql语句中,有可能成为最后一个分割元素的'limit','values','where', 按优先级别,先处理'limit',再处理'values'或'where'.....
处理完得到sql_dic后,就是你按不同命令执行,对数据文件的增删改查,最后返回处理结果!!
示例代码
#_*_coding:utf-8_*_ #Author:JayeHe importre importos defsql_parse(sql,key_lis): ''' 解析sql命令字符串,按照key_lis列表里的元素分割sql得到字典形式的命令sql_dic :paramsql: :paramkey_lis: :return: ''' sql_list=[] sql_dic={} foriinkey_lis: b=[j.strip()forjinsql.split(i)] iflen(b)>1: iflen(sql.split('limit'))>1: sql_dic['limit']=sql.split('limit')[-1] ifi=='where'ori=='values': sql_dic[i]=b[-1] ifsql_list: sql_dic[sql_list[-1]]=b[0] sql_list.append(i) sql=b[-1] else: sql=b[0] ifsql_dic.get('select'): ifnotsql_dic.get('from')andnotsql_dic.get('where'): sql_dic['from']=b[-1] ifsql_dic.get('select'): sql_dic['select']=sql_dic.get('select').split(',') ifsql_dic.get('where'): sql_dic['where']=where_parse(sql_dic.get('where')) returnsql_dic defwhere_parse(where): ''' 格式化where字符串为列表where_list,用'and','or','not'分割字符串 :paramwhere: :return: ''' casual_l=[where] logic_key=['and','or','not'] forjinlogic_key: foriincasual_l: ifinotinlogic_key: iflen(i.split(j))>1: ele=i.split(j) index=casual_l.index(i) casual_l.pop(index) casual_l.insert(index,ele[0]) casual_l.insert(index+1,j) casual_l.insert(index+2,ele[1]) casual_l=[kforkincasual_lifk] where_list=three_parse(casual_l,logic_key) returnwhere_list defthree_parse(casual_l,logic_key): ''' 处理临时列表casual_l中具体的条件,'staff_id>5'-->['staff_id','>','5'] :paramcasual_l: :paramlogic_key: :return: ''' where_list=[] foriincasual_l: ifinotinlogic_key: b=i.split('like') iflen(b)>1: b.insert(1,'like') where_list.append(b) else: key=['<','=','>'] new_lis=[] opt='' lis=[jforjinre.split('([=<>])',i)ifj] forkinlis: ifkinkey: opt+=k else: new_lis.append(k) new_lis.insert(1,opt) where_list.append(new_lis) else: where_list.append(i) returnwhere_list defsql_action(sql_dic,title): ''' 把解析好的sql_dic分发给相应函数执行处理 :paramsql_dic: :paramtitle: :return: ''' key={'select':select, 'insert':insert, 'delete':delete, 'update':update} res=[] foriinsql_dic: ifiinkey: res=key[i](sql_dic,title) returnres defselect(sql_dic,title): ''' 处理select语句命令 :paramsql_dic: :paramtitle: :return: ''' withopen('staff_data','r',encoding='utf-8')asfh: filter_res=where_action(fh,sql_dic.get('where'),title) limit_res=limit_action(filter_res,sql_dic.get('limit')) search_res=search_action(limit_res,sql_dic.get('select'),title) returnsearch_res definsert(sql_dic,title): ''' 处理insert语句命令 :paramsql_dic: :paramtitle: :return: ''' withopen('staff_data','r+',encoding='utf-8')asf: data=f.readlines() phone_list=[i.strip().split(',')[4]foriindata] ins_count=0 ifnotdata: new_id=1 else: last=data[-1] last_id=int(last.split(',')[0]) new_id=last_id+1 record=sql_dic.get('values').split('/') foriinrecord: ifi.split(',')[3]inphone_list: print('\033[1;31m%s手机号已存在\033[0m'%i) else: new_record='%s,%s\n'%(str(new_id),i) f.write(new_record) new_id+=1 ins_count+=1 f.flush() return['insertsuccessful'],[str(ins_count)] defdelete(sql_dic,title): ''' 处理delete语句命令 :paramsql_dic: :paramtitle: :return: ''' withopen('staff_data','r',encoding='utf-8')asr_file,\ open('staff_data_bak','w',encoding='utf-8')asw_file: del_count=0 forlineinr_file: dic=dict(zip(title.split(','),line.split(','))) filter_res=logic_action(dic,sql_dic.get('where')) ifnotfilter_res: w_file.write(line) else: del_count+=1 w_file.flush() os.remove('staff_data') os.rename('staff_data_bak','staff_data') return['deletesuccessful'],[str(del_count)] defupdate(sql_dic,title): ''' 处理update语句命令 :paramsql_dic: :paramtitle: :return: ''' set_l=sql_dic.get('set').strip().split(',') set_list=[i.split('=')foriinset_l] update_count=0 withopen('staff_data','r',encoding='utf-8')asr_file,\ open('staff_data_bak','w',encoding='utf-8')asw_file: forlineinr_file: dic=dict(zip(title.split(','),line.strip().split(','))) filter_res=logic_action(dic,sql_dic.get('where')) iffilter_res: foriinset_list: k=i[0] v=i[-1] dic[k]=v line=[dic[i]foriintitle.split(',')] update_count+=1 line=','.join(line)+'\n' w_file.write(line) w_file.flush() os.remove('staff_data') os.rename('staff_data_bak','staff_data') return['updatesuccessful'],[str(update_count)] defwhere_action(fh,where_list,title): ''' 具体处理where_list里的所有条件 :paramfh: :paramwhere_list: :paramtitle: :return: ''' res=[] iflen(where_list)!=0: forlineinfh: dic=dict(zip(title.split(','),line.strip().split(','))) ifdic['name']!='name': logic_res=logic_action(dic,where_list) iflogic_res: res.append(line.strip().split(',')) else: res=[i.split(',')foriinfh.readlines()] returnres pass deflogic_action(dic,where_list): ''' 判断数据文件中每一条是否符合where_list条件 :paramdic: :paramwhere_list: :return: ''' logic=[] forexpinwhere_list: iftype(exp)islist: exp_k,opt,exp_v=exp ifexp[1]=='=': opt='==' logical_char="'%s'%s'%s'"%(dic[exp_k],opt,exp_v) ifopt!='like': exp=str(eval(logical_char)) else: ifexp_vindic[exp_k]: exp='True' else: exp='False' logic.append(exp) res=eval(''.join(logic)) returnres deflimit_action(filter_res,limit_l): ''' 用列表切分处理显示符合条件的数量 :paramfilter_res: :paramlimit_l: :return: ''' iflimit_l: index=int(limit_l[0]) res=filter_res[:index] else: res=filter_res returnres defsearch_action(limit_res,select_list,title): ''' 处理需要查询并显示的title和相应数据 :paramlimit_res: :paramselect_list: :paramtitle: :return: ''' res=[] fields_list=title.split(',') ifselect_list[0]=='*': res=limit_res else: fields_list=select_list fordatainlimit_res: dic=dict(zip(title.split(','),data)) r_l=[] foriinfields_list: r_l.append((dic[i].strip())) res.append(r_l) returnfields_list,res if__name__=='__main__': withopen('staff_data','r',encoding='utf-8')asf: title=f.readline().strip() key_lis=['select','insert','delete','update','from','into','set','values','where','limit'] whileTrue: sql=input('请输入sql命令,退出请输入exit:').strip() sql=re.sub('','',sql) iflen(sql)==0:continue ifsql=='exit':break sql_dict=sql_parse(sql,key_lis) fields_list,fields_data=sql_action(sql_dict,title) print('\033[1;33m结果如下:\033[0m') print('-'.join(fields_list)) fordatainfields_data: print('-'.join(data))
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。