作业 1: 员工信息表程序,实现增删改查操作
可进行模糊查询,语法至少支持下面3种:
select name,age from staff_table where age > 22
select * from staff_table where dept = "IT"
select * from staff_table where enroll_date like "2013"
查到的信息,打印后,最后面还要显示查到的条数
可创建新员工纪录,以phone做唯一键,staff_id需自增
可删除指定员工信息纪录,输入员工id,即可删除
可修改员工信息,语法如下:
UPDATE staff_table SET dept="Market" WHERE where dept = "IT"
注意:以上需求,要充分使用函数,请尽你的最大限度来减少重复代码
实现了统一入口,自动判断增删改查,输出结果:
详细代码:
#!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
import os ,sys
BASE_DIR=os.path.dirname(os.path.abspath(__file__))#获取相对路径转为绝对路径赋于变量
sys.path.append(BASE_DIR)#增加环境变量 select_='select'#定义关键字
from_='from'
where_='where'
update_='update'
set_='set'
WHERE_='WHERE'
UPDATE_='UPDATE'
SET_='SET'
delete_='delete'
insert_='insert'
values_='values'
into_='into' def sql_parsing(sql):#sql解析函数 主入口
if sql.startswith('select'):#判断语句类型
_dict_=select_par(sql)#调用相关函数
elif sql.startswith('update') or sql.startswith('UPDATE') :#判断语句类型
_dict_=update_par(sql)
elif sql.startswith('insert'):#判断语句类型
_dict_=insert_par(sql)
elif sql.startswith('delete'):
_dict_=delete_par(sql)
else:
return print('输入有误,请重新输入!')
return _dict_#返回解析完成的列表 def select_par(sql):#select语句的解析函数
list_key=parsing(sql,index_select=-1,index_from=-1,index_where=-1,select_=select_,where_=where_,from_=from_)#查询调用
return list_key
def update_par(sql):#update语句的解析函数
list_key=parsing(sql,index_update=-1,index_set=-1,update_=update_,set_=set_,where_=where_)#更新修改调用
return list_key
def insert_par(sql):#insert语句的解析函数
list_key=parsing(sql,index_insert=-1,index_into=-1,index_values=-1,insert_=insert_,values_=values_)#添加调用
return list_key def delete_par(sql):#delete语句的解析函数
list_key=parsing(sql,index_delete=-1,index_from=-1,index_where=-1,delete_=delete_,where_=where_,from_=from_)#删除调用
return list_key #where子句再格式化
def where_chard(str_list):#where子句再格式化
key=[]#定义一个临时列表变量
list_key=['<','>','=']#运算符
tag=False#定义点为假
str_=''#字符串拼接变量
chrd=''#运算符拼接
for i in str_list:
if i in list_key :#如果点为假,并且在关键字字典中
tag=True#点为真
if len(str_)!=0:#不为空时
key.append(str_)#列表添加字符串
str_=''
chrd+=i#运算符拼接
if not tag :#点为假
str_+=i#字符拼接
if tag and i not in list_key:#如果点为真,并且在不在关键字字典中
tag=False#转为假
key.append(chrd)#关键字字典中所对应的添加这个值
chrd=''
str_+=i
key.append(str_)
if len(key)==1:#判断like运算符
key=key[0].split('like')#用like分割
key.insert(1,'like')
cq='\"'
if cq in key[2]:#判断是否有包含 ”
key[2]=cq_c(key[2],cq)
return key#返回一个列表
#格式化where 子句函数
def where_format(where_list):#格式化where 子句函数
list_format=[]
key_=['and','or','not']
str_=''#字符连接变量
for i in where_list:
if len(i)==0:continue#如果为空就不连接
if i not in key_:##如果不是关键字就进行连接
str_+=i
elif i in key_ and len(str_)!=0:
str_=where_chard(str_)#进行再处理
list_format.append(str_)#之前的字符串添加到列表
list_format.append(i)#关键 字添加到列表
str_=''#清空变量 备用
str_=where_chard(str_)#进行再处理
list_format.append(str_)#最后的字符串
return list_format #格式化select函数
def select_format(select_list):#格式化select函数
if select_list[0]=='*':#如果为* 就不改动
return select_list#直接返回
else:
list_=str_conn(select_list).split(',')#字符串连接函数
return list_
#字符串连接函数
def str_conn(list):
str_=''
for i in list:
str_+=i
return str_ #语句的解析总函数
def parsing(sql,**kwargs):#语句的解析总函数
list_l=sql.split(' ')#分割存为列表
index_from=-1#下标定义from
index_select=-1#select
index_where=-1#where
index_update=-1#update
index_set=-1#set
index_delete=-1#delete
index_insert=-1#insert
index_values=-1#valuse
index_into=-1
list_key={'select':[],'update':[],'delete':[],'insert':[],'set':[],'from':[],'into':[],'where':[],'values':[]}#定义要处理的关键字字典
for index,i in enumerate(list_l):#获取下标
if i==select_:#如果是关键字select字典下标
index_select=index
if i==update_ or i==UPDATE_:#如果是关键字update字典下标,全部转为小写
index_update=index
if i==set_ or i==SET_:
index_set=index
if i==insert_:#如果是关键字insert字典下标
index_insert=index
if i==into_:
index_into=index
if i==values_:
index_values=index
if i==delete_:
index_delete=index
if i==from_:#如果是关键字from字典下标
index_from=index
if i==where_ or i==WHERE_:#如果是关键字where字典下标
index_where=index for index,i in enumerate(list_l):#用下标界定,对进行关键字字典的添加
if index_select !=-1 and index>index_select and index<index_from:#在select和from中添加到select中,不为空时
list_key[select_].append(i)#添加当前值
if index_update !=-1 and index>index_update and index<index_set:#如果是update语句添加一个1值
list_key[update_].append(i)
if index_insert !=-1 and index==index_insert:#如果是insert语句添加一个1值
list_key[insert_].append(1)
if index_into !=-1 and index>index_into and index<index_values:#如果是into后的语句添加一个1值
list_key[into_].append(i)
if index_delete !=-1 and index==index_delete:#如果是delete语句添加一个1值
list_key[delete_].append(1)
if index_from!=-1 and index>index_from and index<index_where:#添加from中的值
list_key[from_].append(i)
if index_set!=-1 and index>index_set and index<index_where:#添加set中的值
list_key[set_].append(i)
if index_where!=-1 and index>index_where:#添加到where列表中
list_key[where_].append(i)
if index_values!=-1 and index>index_values:#添加到values列表中
list_key[values_].append(i)
if list_key.get(where_):#如果字典在的列表不为空
list_key[where_]=where_format(list_key.get(where_))#进行格式化,重新赋于字典,调用格式化函数
if list_key.get(select_):#如果字典select在的列表不为空
list_key[select_]=select_format(list_key.get(select_))#进行格式化,重新赋于字典
if list_key.get(values_):#如果字典values在的列表不为空
list_key[values_]=select_format(list_key.get(values_))#进行格式化,重新赋于字典
if list_key.get(set_):#如果字典set在的列表不为空
list_key[set_]=where_format(list_key.get(set_))#进行格式化,重新赋于字典
return list_key #执行部分 主入口
def sql_perform(sql_dict):#执行函数
if sql_dict[from_]:
file_name='db\\'+sql_dict[from_][0]#获取文件路径
elif sql_dict[into_]:#判断是不是在into里面
file_name='db\\'+sql_dict[into_][0]#获取文件路径
else:
file_name='db\\'+sql_dict[update_][0]#获取文件路径
user_info=open(file_name,'r+',encoding='utf-8')
key=['id','name','age','phone','dept','enroll_date']
if sql_dict[select_]:#不为空,就调用select的函数
perform_select(sql_dict,user_info,key)#传入 字典调用select 函数
user_info.close()#关闭文件
if sql_dict[update_]:#不为空,就调用update的函数
perform_update(sql_dict,user_info,key,file_name)#传入 字典调用update函数
user_info.close()#关闭文件
if sql_dict[insert_]:#不为空,就调用insert的函数
perform_insert(sql_dict,user_info,file_name,key)#传入 字典调用insert函数
if sql_dict[delete_]:#不为空,就调用insert的函数
del_tag=True#标示是删除
perform_update(sql_dict,user_info,key,file_name,del_tag) #执行select操作的函数
def perform_select(sql_dict,user_info,key):#执行select操作的函数
list_l=[]#定义要输出的列表
conut=0#定义计数
for line in user_info:
file=line.strip().split(',')#每一行存为列表
file_dict=dict(zip(key,file))#用zip拉链成字典 file_dict
if sql_dict[where_]:#where条件不为空
where_l=sql_dict[where_]#定义where子句变量
if where_conn(where_l,file_dict):#调用where子句判断函数 如果返回为真
if sql_dict[select_][0]!='*':#如果查询条件不为 *
file.pop(0)#删除ID号
file_dict2=dict(zip(sql_dict[select_],file))#进行对比拼接 如只输出 name age
list_l.append(file_dict2)
else:
list_l.append(file_dict)#添加到输出的列表
conut+=1
for i in list_l:#输出
print(i)
print('总共查询结果数为:%s 条'%conut)
return #返回处理后的信息 #where子句判断函数where函数传入员工字典,where子句
def where_conn(where_l,file_dict):#where子句判断函数where函数传入员工字典,where子句
reg=[]#临时列表
for i in where_l:#循环判断where_l中的条件
if type(i) is list:#判断是否是列表
i_key,conn,i_val=i#三元赋值 key,运算,内容
if i[1]=='=':#如果运算符是 = 进行拼接
conn=i[1]+'='
if file_dict[i_key].isdigit():#如果员工表内键对应的值是整数
dict_vla=int(file_dict[i_key])#员工表内的值赋于一个变量
i_vla=int(i_val)#where条件语句的值赋于一个变量 用于对比
else:#否则
dict_vla="'%s'"%file_dict[i_key]#员工表内键对应的值赋于字符串
if 'like' in i:
if i_val in dict_vla:#如果where条件
i='True'#返回真
else:
i='False'#返回假
else:
i=str(eval("%s%s%s"%(dict_vla,conn,i_val)))#进行员工表与条件的比对 再转为字符串
reg.append(i)#判断后添加到列表
reg=eval(' '.join(reg))#用 join拼接,最后运算
return reg #执行update操作的函数
def perform_update(sql_dict,user_info,key,file_name,tag=False):#执行update操作的函数
list_l=[]#定义要更新的列表
conut=0#定义计数
for line in user_info:
file=line.strip().split(',')#每一行存为列表
file_dict=dict(zip(key,file))#用zip拉链成字典 file_dict
if sql_dict[where_]:#where条件不为空
where_l=sql_dict[where_]#定义where子句变量
set_l=sql_dict[set_]#定义要更新的字符
if where_conn(where_l,file_dict):#调用where子句判断函数 如果返回为真
if tag:#如果为删除标示
line=''
list_l.append(line)#添加到文件列表
conut+=1
else:
line_list=line.split(',')#分割为列表
cq='\"'
if cq in set_l[0][2]:#判断是否有包含 ”
set_l[0][2]=cq_c(set_l[0][2],cq)
for index, i in enumerate(line_list):#判断替换
if i == file_dict[where_l[0][0]]:
line_list[index]=set_l[0][2]#对字典进行替换
line=','.join(line_list)
list_l.append(line)#添加到文件列表
conut+=1
else:
list_l.append(line)
write_file(list_l,file_name)#写入文件函数
if tag:
print('总共删除了 %s 条记录!'%conut)
else:
print('总共更新了 %s 条记录!'%conut)
return #返回处理后的信息
#去 " 函数
def cq_c(set_l,cq):
set__l=''
for i in set_l:
if i==cq:
pass
else:
set__l+=i
return set__l
#写文件函数
def write_file(list_l,file_name):#写文件函数
with open(file_name,'w',encoding='utf-8') as new_file:
for i in list_l:
new_file.write(i)#写入文件
new_file.flush() #执行insert操作的函数
def perform_insert(sql_dict,user_info,file_name,key):#执行insert操作的函数
list_user=sql_dict[values_]#提取要更新的列表
phone_=list_user[2]#提取电话号码
conut=1
tag=True
for line in user_info:
conut+=1#统计行数
file=line.strip().split(',')#每一行存为列表
file_dict=dict(zip(key,file))#用zip拉链成字典 file_dict
if phone_==file_dict['phone']:#如果有存在
tag=False
break
else:
pass
if tag:#如果检测结果为真才能添加\
list_user.insert(0,str(conut))#将字ID插入列表
str_user='\n%s'%','.join(list_user)#需要加回车
user_info.close()#关闭文件
with open(file_name,'a',encoding='utf-8') as file_a:
file_a.write(str_user)#
file_a.flush()
return print('信息已经更新!')
else:
return print('电话号码已经存在,请重新输入!') #执行delete操作的函数
def perform_delete(sql_dict):#执行delete操作的函数
select_dict=sql_dict
return select_dict#返回处理后的信息 #程序开始
print("\033[35;1m欢迎进入员工信息表查询系统\033[0m".center(60,'='))
if __name__ =='__main__':
while True:
print('查询修改示例'.center(50,'-').center(60,' '))
print('''
\033[32;1m1、【查】: select name,age from staff_table where age>22 and age<35 or name like li\033[0m
\033[33;1m2、【改】: UPDATE staff_table SET dept="Market" WHERE dept="IT"\033[0m
\033[34;1m3、【增】: insert into staff_table values Alex Li,22,13651054608,IT,2013-04-01\033[0m
\033[31;1m3、【删】: delete from staff_table where id=5 \033[0m
\033[37;1m4、【退】: exit\033[0m
''')
sql=input('sql->').strip()#定义显示提示符
if sql=='exit':break#如果输入exit退出
if sql==0:continue#如何没输入重新提示
sql_dict=sql_parsing(sql)#解析输入的sql语句 赋于变量
try:
sql_action=sql_perform(sql_dict)#执行解析后的语句 传入解析后的变量
except Exception as e:
print('你的输入格式有误,请重新输入!')
两天半时间才搞定,休息一下下