具体需求:
员工信息表程序,实现增删改查操作:
可进行模糊查询,语法支持下面3种:
select name,age from staff_data where age > 22 多个查询参数name,age 用','分割
select * from staff_data where dept = 人事
select * from staff_data where enroll_date like 2013
查到的信息,打印后,最后面还要显示查到的条数
可创建新员工纪录,以phone做唯一键,phone存在即提示,staff_id需自增,添加多个记录record1/record2中间用'/'分割
insert into staff_data values record1/record2
可删除指定员工信息纪录,输入员工id,即可删除
delete from staff_data where staff_id>=5andstaff_id<=10
可修改员工信息,语法如下:
update staff_table set dept=Market,phone=13566677787 where dept = 运维 多个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后,就是你按不同命令执行,对数据文件的增删改查,最后返回处理结果!!
1 # _*_coding:utf-8_*_ 2 # Author:Jaye He 3 import re 4 import os 5 6 7 def sql_parse(sql, key_lis): 8 ''' 9 解析sql命令字符串,按照key_lis列表里的元素分割sql得到字典形式的命令sql_dic 10 :param sql: 11 :param key_lis: 12 :return: 13 ''' 14 sql_list = [] 15 sql_dic = {} 16 for i in key_lis: 17 b = [j.strip() for j in sql.split(i)] 18 if len(b) > 1: 19 if len(sql.split('limit')) > 1: 20 sql_dic['limit'] = sql.split('limit')[-1] 21 if i == 'where' or i == 'values': 22 sql_dic[i] = b[-1] 23 if sql_list: 24 sql_dic[sql_list[-1]] = b[0] 25 sql_list.append(i) 26 sql = b[-1] 27 else: 28 sql = b[0] 29 if sql_dic.get('select'): 30 if not sql_dic.get('from') and not sql_dic.get('where'): 31 sql_dic['from'] = b[-1] 32 if sql_dic.get('select'): 33 sql_dic['select'] = sql_dic.get('select').split(',') 34 if sql_dic.get('where'): 35 sql_dic['where'] = where_parse(sql_dic.get('where')) 36 return sql_dic 37 38 39 def where_parse(where): 40 ''' 41 格式化where字符串为列表where_list,用'and', 'or', 'not'分割字符串 42 :param where: 43 :return: 44 ''' 45 casual_l = [where] 46 logic_key = ['and', 'or', 'not'] 47 for j in logic_key: 48 for i in casual_l: 49 if i not in logic_key: 50 if len(i.split(j)) > 1: 51 ele = i.split(j) 52 index = casual_l.index(i) 53 casual_l.pop(index) 54 casual_l.insert(index, ele[0]) 55 casual_l.insert(index+1, j) 56 casual_l.insert(index+2, ele[1]) 57 casual_l = [k for k in casual_l if k] 58 where_list = three_parse(casual_l, logic_key) 59 return where_list 60 61 62 def three_parse(casual_l, logic_key): 63 ''' 64 处理临时列表casual_l中具体的条件,'staff_id>5'-->['staff_id','>','5'] 65 :param casual_l: 66 :param logic_key: 67 :return: 68 ''' 69 where_list = [] 70 for i in casual_l: 71 if i not in logic_key: 72 b = i.split('like') 73 if len(b) > 1: 74 b.insert(1, 'like') 75 where_list.append(b) 76 else: 77 key = ['<', '=', '>'] 78 new_lis = [] 79 opt = '' 80 lis = [j for j in re.split('([=<>])', i) if j] 81 for k in lis: 82 if k in key: 83 opt += k 84 else: 85 new_lis.append(k) 86 new_lis.insert(1, opt) 87 where_list.append(new_lis) 88 else: 89 where_list.append(i) 90 return where_list 91 92 93 def sql_action(sql_dic, title): 94 ''' 95 把解析好的sql_dic分发给相应函数执行处理 96 :param sql_dic: 97 :param title: 98 :return: 99 ''' 100 key = {'select': select, 101 'insert': insert, 102 'delete': delete, 103 'update': update} 104 res = [] 105 for i in sql_dic: 106 if i in key: 107 res = key[i](sql_dic, title) 108 return res 109 110 111 def select(sql_dic, title): 112 ''' 113 处理select语句命令 114 :param sql_dic: 115 :param title: 116 :return: 117 ''' 118 with open('staff_data', 'r', encoding='utf-8') as fh: 119 filter_res = where_action(fh, sql_dic.get('where'), title) 120 limit_res = limit_action(filter_res, sql_dic.get('limit')) 121 search_res = search_action(limit_res, sql_dic.get('select'), title) 122 return search_res 123 124 125 def insert(sql_dic, title): 126 ''' 127 处理insert语句命令 128 :param sql_dic: 129 :param title: 130 :return: 131 ''' 132 with open('staff_data', 'r+', encoding='utf-8') as f: 133 data = f.readlines() 134 phone_list = [i.strip().split(',')[4] for i in data] 135 ins_count = 0 136 if not data: 137 new_id = 1 138 else: 139 last = data[-1] 140 last_id = int(last.split(',')[0]) 141 new_id = last_id+1 142 record = sql_dic.get('values').split('/') 143 for i in record: 144 if i.split(',')[3] in phone_list: 145 print('