利用python模拟sql语句对员工表格进行增删改查


Posted in Python onJuly 05, 2017

本文主要给大家介绍了关于python模拟sql语句对员工表格进行增删改查的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍:

具体需求:

员工信息表程序,实现增删改查操作:

可进行模糊查询,语法支持下面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后,就是你按不同命令执行,对数据文件的增删改查,最后返回处理结果!!

示例代码

# _*_coding:utf-8_*_
# Author:Jaye He
import re
import os


def sql_parse(sql, key_lis):
 '''
 解析sql命令字符串,按照key_lis列表里的元素分割sql得到字典形式的命令sql_dic
 :param sql:
 :param key_lis:
 :return:
 '''
 sql_list = []
 sql_dic = {}
 for i in key_lis:
  b = [j.strip() for j in sql.split(i)]
  if len(b) > 1:
   if len(sql.split('limit')) > 1:
    sql_dic['limit'] = sql.split('limit')[-1]
   if i == 'where' or i == 'values':
    sql_dic[i] = b[-1]
   if sql_list:
    sql_dic[sql_list[-1]] = b[0]
   sql_list.append(i)
   sql = b[-1]
  else:
   sql = b[0]
  if sql_dic.get('select'):
   if not sql_dic.get('from') and not sql_dic.get('where'):
    sql_dic['from'] = b[-1]
 if sql_dic.get('select'):
  sql_dic['select'] = sql_dic.get('select').split(',')
 if sql_dic.get('where'):
  sql_dic['where'] = where_parse(sql_dic.get('where'))
 return sql_dic


def where_parse(where):
 '''
 格式化where字符串为列表where_list,用'and', 'or', 'not'分割字符串
 :param where:
 :return:
 '''
 casual_l = [where]
 logic_key = ['and', 'or', 'not']
 for j in logic_key:
  for i in casual_l:
   if i not in logic_key:
    if len(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 = [k for k in casual_l if k]
 where_list = three_parse(casual_l, logic_key)
 return where_list


def three_parse(casual_l, logic_key):
 '''
 处理临时列表casual_l中具体的条件,'staff_id>5'-->['staff_id','>','5']
 :param casual_l:
 :param logic_key:
 :return:
 '''
 where_list = []
 for i in casual_l:
  if i not in logic_key:
   b = i.split('like')
   if len(b) > 1:
    b.insert(1, 'like')
    where_list.append(b)
   else:
    key = ['<', '=', '>']
    new_lis = []
    opt = ''
    lis = [j for j in re.split('([=<>])', i) if j]
    for k in lis:
     if k in key:
      opt += k
     else:
      new_lis.append(k)
    new_lis.insert(1, opt)
    where_list.append(new_lis)
  else:
   where_list.append(i)
 return where_list


def sql_action(sql_dic, title):
 '''
 把解析好的sql_dic分发给相应函数执行处理
 :param sql_dic:
 :param title:
 :return:
 '''
 key = {'select': select,
   'insert': insert,
   'delete': delete,
   'update': update}
 res = []
 for i in sql_dic:
  if i in key:
   res = key[i](sql_dic, title)
 return res


def select(sql_dic, title):
 '''
 处理select语句命令
 :param sql_dic:
 :param title:
 :return:
 '''
 with open('staff_data', 'r', encoding='utf-8') as fh:
  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)
 return search_res


def insert(sql_dic, title):
 '''
 处理insert语句命令
 :param sql_dic:
 :param title:
 :return:
 '''
 with open('staff_data', 'r+', encoding='utf-8') as f:
  data = f.readlines()
  phone_list = [i.strip().split(',')[4] for i in data]
  ins_count = 0
  if not data:
   new_id = 1
  else:
   last = data[-1]
   last_id = int(last.split(',')[0])
   new_id = last_id+1
  record = sql_dic.get('values').split('/')
  for i in record:
   if i.split(',')[3] in phone_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 ['insert successful'], [str(ins_count)]


def delete(sql_dic, title):
 '''
 处理delete语句命令
 :param sql_dic:
 :param title:
 :return:
 '''
 with open('staff_data', 'r', encoding='utf-8') as r_file,\
   open('staff_data_bak', 'w', encoding='utf-8') as w_file:
  del_count = 0
  for line in r_file:
   dic = dict(zip(title.split(','), line.split(',')))
   filter_res = logic_action(dic, sql_dic.get('where'))
   if not filter_res:
    w_file.write(line)
   else:
    del_count += 1
  w_file.flush()
 os.remove('staff_data')
 os.rename('staff_data_bak', 'staff_data')
 return ['delete successful'], [str(del_count)]


def update(sql_dic, title):
 '''
 处理update语句命令
 :param sql_dic:
 :param title:
 :return:
 '''
 set_l = sql_dic.get('set').strip().split(',')
 set_list = [i.split('=') for i in set_l]
 update_count = 0
 with open('staff_data', 'r', encoding='utf-8') as r_file,\
   open('staff_data_bak', 'w', encoding='utf-8') as w_file:
  for line in r_file:
   dic = dict(zip(title.split(','), line.strip().split(',')))
   filter_res = logic_action(dic, sql_dic.get('where'))
   if filter_res:
    for i in set_list:
     k = i[0]
     v = i[-1]
     dic[k] = v
    line = [dic[i] for i in title.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 ['update successful'], [str(update_count)]


def where_action(fh, where_list, title):
 '''
 具体处理where_list里的所有条件
 :param fh:
 :param where_list:
 :param title:
 :return:
 '''
 res = []
 if len(where_list) != 0:
  for line in fh:
   dic = dict(zip(title.split(','), line.strip().split(',')))
   if dic['name'] != 'name':
    logic_res = logic_action(dic, where_list)
    if logic_res:
     res.append(line.strip().split(','))
 else:
  res = [i.split(',') for i in fh.readlines()]
 return res
 pass


def logic_action(dic, where_list):
 '''
 判断数据文件中每一条是否符合where_list条件
 :param dic:
 :param where_list:
 :return:
 '''
 logic = []
 for exp in where_list:
  if type(exp) is list:
   exp_k, opt, exp_v = exp
   if exp[1] == '=':
    opt = '=='
   logical_char = "'%s'%s'%s'" % (dic[exp_k], opt, exp_v)
   if opt != 'like':
    exp = str(eval(logical_char))
   else:
    if exp_v in dic[exp_k]:
     exp = 'True'
    else:
     exp = 'False'
  logic.append(exp)
 res = eval(' '.join(logic))
 return res


def limit_action(filter_res, limit_l):
 '''
 用列表切分处理显示符合条件的数量
 :param filter_res:
 :param limit_l:
 :return:
 '''
 if limit_l:
  index = int(limit_l[0])
  res = filter_res[:index]
 else:
  res = filter_res
 return res


def search_action(limit_res, select_list, title):
 '''
 处理需要查询并显示的title和相应数据
 :param limit_res:
 :param select_list:
 :param title:
 :return:
 '''
 res = []
 fields_list = title.split(',')
 if select_list[0] == '*':
  res = limit_res
 else:
  fields_list = select_list
  for data in limit_res:
   dic = dict(zip(title.split(','), data))
   r_l = []
   for i in fields_list:
    r_l.append((dic[i].strip()))
   res.append(r_l)
 return fields_list, res


if __name__ == '__main__':
 with open('staff_data', 'r', encoding='utf-8') as f:
  title = f.readline().strip()
 key_lis = ['select', 'insert', 'delete', 'update', 'from', 'into', 'set', 'values', 'where', 'limit']
 while True:
  sql = input('请输入sql命令,退出请输入exit:').strip()
  sql = re.sub(' ', '', sql)
  if len(sql) == 0:continue
  if sql == '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))
  for data in fields_data:
   print('-'.join(data))

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Python时区设置方法与pytz查询时区教程
Nov 27 Python
python实现定时播放mp3
Mar 29 Python
对于Python中RawString的理解介绍
Jul 07 Python
Python创建xml文件示例
Mar 22 Python
基于Python对数据shape的常见操作详解
Dec 25 Python
利用python开发app实战的方法
Jul 09 Python
浅谈python元素如何去重,去重后如何保持原来元素的顺序不变
Feb 28 Python
python实时监控logstash日志代码
Apr 27 Python
Python用Jira库来操作Jira
Dec 28 Python
python实现监听键盘
Apr 26 Python
Python 如何利用ffmpeg 处理视频素材
Nov 27 Python
Python编写车票订购系统 Python实现快递收费系统
Aug 14 Python
利用python实现简单的循环购物车功能示例代码
Jul 05 #Python
用python做一个搜索引擎(Pylucene)的实例代码
Jul 05 #Python
Python对象类型及其运算方法(详解)
Jul 05 #Python
python数据预处理之将类别数据转换为数值的方法
Jul 05 #Python
利用Python3分析sitemap.xml并抓取导出全站链接详解
Jul 04 #Python
在django中使用自定义标签实现分页功能
Jul 04 #Python
详解django中自定义标签和过滤器
Jul 03 #Python
You might like
3
2006/10/09 PHP
php whois查询API制作方法
2011/06/23 PHP
php结合ACCESS的跨库查询功能
2015/06/12 PHP
PHP实现的简单AES加密解密算法实例
2017/05/29 PHP
由JavaScript技术实现的web小游戏(不含网游)
2010/06/12 Javascript
jQuery 阴影插件代码分享
2012/01/09 Javascript
jquery如何获取复选框的值
2013/12/12 Javascript
js 绑定键盘鼠标事件示例代码
2014/02/12 Javascript
JavaScript获取元素尺寸和大小操作总结
2015/02/27 Javascript
js实现精美的银灰色竖排折叠菜单
2015/05/16 Javascript
不用一句js代码初始化组件
2016/01/27 Javascript
基于javascript实现动态时钟效果
2020/08/18 Javascript
Bootstrap 粘页脚效果
2016/03/28 Javascript
js模拟百度模糊搜索的实例
2017/08/04 Javascript
详解Vue 多级组件透传新方法provide/inject
2018/05/09 Javascript
JS+CSS3实现的简易钟表效果示例
2019/04/13 Javascript
Vue.js中该如何自己维护路由跳转记录
2019/05/19 Javascript
详细分析vue响应式原理
2020/06/22 Javascript
Openlayers实现测量功能
2020/09/25 Javascript
[01:31:22]Ti4 循环赛第四日附加赛LGD vs Mouz
2014/07/13 DOTA
[39:07]LGD vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.21
2018/08/22 DOTA
用Python实现服务器中只重载被修改的进程的方法
2015/04/30 Python
Python实现简单网页图片抓取完整代码实例
2017/12/15 Python
对Python函数设计规范详解
2019/07/19 Python
Python更换pip源方法过程解析
2020/05/19 Python
Mavi牛仔裤美国官网:土耳其著名牛仔品牌
2016/09/24 全球购物
稀有和绝版书籍:Biblio.com
2017/02/02 全球购物
Kent & Curwen:与大卫·贝克汉姆合作
2017/06/13 全球购物
俄罗斯电子产品、计算机和家用电器购物网站:OLDI
2019/10/27 全球购物
大学生个人自荐信样本
2014/03/02 职场文书
夫妻忠诚协议书范本
2014/11/17 职场文书
违反纪律检讨书范文
2015/05/07 职场文书
二审代理词范文
2015/05/25 职场文书
想要创业,那么你做好准备了吗?
2019/07/01 职场文书
2019年幼儿园家长接送责任书
2019/10/29 职场文书
golang中的struct操作
2021/11/11 Golang