練習:員工信息表

来源:http://www.cnblogs.com/Xunmeng888/archive/2017/02/10/6385205.html
-Advertisement-
Play Games

要求: 1 #_*_coding:utf-8_*_ 2 #第一部分:sql解析 3 import os,time 4 def sql_parse(sql): 5 ''' 6 sql_parse >insert_parse,delete_parse,update_parse,select_parse ...


要求:

 
  1 #_*_coding:utf-8_*_
  2 #第一部分:sql解析
  3 import os,time
  4 def sql_parse(sql):
  5     '''
  6     sql_parse--->insert_parse,delete_parse,update_parse,select_parse
  7     sql解析總控
  8     :param sql:用戶輸入的字元串
  9     :return: 返回字典格式sql解析結果
 10     '''''
 11     parse_func={
 12         'insert':insert_parse,
 13         'delete':delete_parse,
 14         'update':update_parse,
 15         'select':select_parse,
 16     }
 17     sql_l=sql.split(' ')
 18     func=sql_l[0]
 19     res=''
 20     if func in parse_func:
 21         res=parse_func[func](sql_l)
 22     return res
 23 
 24 def insert_parse(sql_l):
 25     # insert into db.t1 values 魯海寶,35,13912015353,測試,2005-06-27
 26     '''
 27     sql解析分支:insert
 28     :param sql_l: sql按照空格分割的列表
 29     :return: 返回字典格式的sql解析結果
 30     '''''
 31     sql_dic={
 32         'func':insert, #函數名
 33         'insert':[],   #insert選項,留出擴展
 34         'into':[],     #表名
 35         'values':[],   #
 36     }
 37     return handle_parse(sql_l,sql_dic)
 38 
 39 def delete_parse(sql_l):
 40     # delete from db.t1 where id=1
 41     '''
 42     sql解析分支:delete
 43     :param sql_l: sql按照空格分割的列表
 44     :return: 返回字典格式的sql解析結果
 45     '''''
 46     sql_dic={
 47         'func':delete,
 48         'delete':[], #delete選項,留出擴展
 49         'from':[],   #表名
 50         'where':[],  #filter條件
 51     }
 52     return handle_parse(sql_l,sql_dic)
 53 
 54 def update_parse(sql_l):
 55     # update db.t1 set id=2 where name='alex'
 56     '''
 57     sql解析分支:update
 58     :param sql_l: sql按照空格分割的列表
 59     :return: 返回字典格式的sql解析結果
 60     '''''
 61     sql_dic={
 62         'func':update,
 63         'update':[], #update選項,留出擴展
 64         'set':[],    #修改的值
 65         'where':[],  #filter條件
 66     }
 67     return handle_parse(sql_l,sql_dic)
 68 
 69 def select_parse(sql_l):
 70     # select * from db1.emp where not id= 1 and name = 'alex' or name= 'sb' limit 3
 71     '''
 72     sql解析分支:select
 73     :param sql_l: sql按照空格分割的列表
 74     :return: 返回字典格式的sql解析結果
 75     '''''
 76     sql_dic={
 77         'func':select,
 78         'select':[], #查詢欄位
 79         'from':[],   #
 80         'where':[],  #filter條件
 81         'limit':[],  #limit條件
 82     }
 83     return handle_parse(sql_l,sql_dic)
 84 
 85 def handle_parse(sql_l,sql_dic):
 86     '''
 87     填充sql_dic
 88     :param sql_l: sql按照空格分割的列表
 89     :param sql_dic: 待填充的字典
 90     :return: 返回字典格式的sql解析結果
 91     '''''
 92     tag=False
 93     for item in sql_l:
 94         if tag and item in sql_dic:
 95             tag=False
 96         if not tag and item in sql_dic:
 97             tag=True
 98             key=item
 99             continue
100         if tag:
101             sql_dic[key].append(item)
102     # print('before \033[33;1m%s\033[0m' %sql_dic)
103     if sql_dic.get('where'):
104         sql_dic['where']=where_parse(sql_dic.get('where'))
105 
106     # print('after \033[33;1m%s\033[0m' %sql_dic)
107     return sql_dic
108 
109 def where_parse(where_l):
110     '''
111     對用戶輸入的where子句後的條件格式化,每個子條件都改成列表形式
112     :param where_l: 用戶輸入where後對應的過濾條件列表
113     :return:
114     '''''
115     res=[]
116     key=['and','or','not']
117     char=''
118     for i in where_l:
119         if len(i) == 0:continue
120         if i in key:
121             if len(char) != 0:
122                 char=three_parse(char) #將每一個小的過濾條件如,name>=1轉換成['name','>=','1']
123                 res.append(char)
124             res.append(i)
125             char=''
126         else:
127           char+=i
128     else:
129         char=three_parse(char)
130         res.append(char)
131     return res
132 
133 def three_parse(exp_str):
134     '''
135     將每一個小的過濾條件如,name>=1轉換成['name','>=','1']
136     :param exp_str:條件表達式的字元串形式,例如'name>=1'
137     :return:
138     '''''
139     # print('three_opt before is \033[34;1m%s\033[0m' %exp_str)
140     key=['>','=','<']
141     res=[]
142     char=''
143     opt=''
144     tag=False
145     for i in exp_str:
146         if i in key:
147             tag=True
148             if len(char) !=0:
149                 res.append(char)
150                 char=''
151             opt+=i
152         if not tag:
153             char+=i
154         if tag and i not in key:
155             tag=False
156             res.append(opt)
157             opt=''
158             char+=i
159     else:
160         res.append(char)
161     # print('res is %s ' %res)
162     #新增like功能
163     if len(res) == 1:#['namelike_ale5']
164         res=res[0].split('like')
165         res.insert(1,'like')
166     return res
167 
168 
169 #第二部分:sql執行
170 def sql_action(sql_dic):
171     '''
172     執行sql的統一介面,內部執行細節對用戶完全透明
173     :param sql:
174     :return:
175     '''''
176     return sql_dic.get('func')(sql_dic)
177 
178 def insert(sql_dic):
179     # insert into db.emp values 李西昌,22,13822117767,運維,2012-01-10
180     print('insert %s' %sql_dic)
181     db,table=sql_dic.get('into')[0].split('.')
182     with open('%s/%s' %(db,table),'ab+') as fh:
183         offs = -100
184         while True:
185             fh.seek(offs,2)
186             lines = fh.readlines()
187             if len(lines)>1:
188                 last = lines[-1]
189                 break
190             offs *= 2
191         last=last.decode(encoding='utf-8')
192         last_id=int(last.split(',')[0])
193         print('insert_data',last.split(',')[-1])
194         new_id=last_id+1
195 
196         record=sql_dic.get('values')[0].split(',')
197 
198         record.insert(0,str(new_id))
199 
200         #['26', 'alex', '18', '13120378203', '運維', '2013-3-1\n']
201         record_str=','.join(record)+'\n'
202         fh.write(bytes(record_str,encoding='utf-8'))
203         fh.flush()
204     return [['insert successful']]
205 
206 def delete(sql_dic):
207     #delete from db.emp where id = 26
208     db,table=sql_dic.get('from')[0].split('.')
209     bak_file=table+'_bak'
210     with open("%s/%s" %(db,table),'r',encoding='utf-8') as r_file,\
211             open('%s/%s' %(db,bak_file),'w',encoding='utf-8') as w_file:
212         del_count=0
213         for line in r_file:
214             title="id,name,age,phone,dept,enroll_date"
215             dic=dict(zip(title.split(','),line.split(',')))
216             filter_res=logic_action(dic,sql_dic.get('where'))
217             if not filter_res:
218                 w_file.write(line)
219             else:
220                 del_count+=1
221         w_file.flush()
222     os.remove("%s/%s" % (db, table))
223     os.rename("%s/%s" %(db,bak_file),"%s/%s" %(db,table))
224     return [[del_count],['delete successful']]
225 
226 def update(sql_dic):
227     # update db.emp set age=24 where name like 李西昌
228     db,table=sql_dic.get('update')[0].split('.')
229     set=sql_dic.get('set')[0].split(',')
230     set_l=[]
231     for i in set:
232         set_l.append(i.split('='))
233     bak_file=table+'_bak'
234     with open("%s/%s" %(db,table),'r',encoding='utf-8') as r_file,\
235             open('%s/%s' %(db,bak_file),'w',encoding='utf-8') as w_file:
236         update_count=0
237         for line in r_file:
238             title="id,name,age,phone,dept,enroll_date"
239             dic=dict(zip(title.split(','),line.split(',')))
240             filter_res=logic_action(dic,sql_dic.get('where'))
241             if filter_res:
242                 for i in set_l:
243                     k=i[0]
244                     v=i[-1].strip("'")
245                     print('k v %s %s' %(k,v))
246                     dic[k]=v
247                 print('change dic is %s ' %dic)
248                 line=[]
249                 for i in title.split(','):
250                     line.append(dic[i])
251                 update_count+=1
252                 line=','.join(line)
253             w_file.write(line)
254 
255         w_file.flush()
256     os.remove("%s/%s" % (db, table))
257     os.rename("%s/%s" %(db,bak_file),"%s/%s" %(db,table))
258     return [[update_count],['update successful']]
259 
260 def select(sql_dic):
261 
262      db,table=sql_dic.get('from')[0].split('.')
263      fh = open("%s/%s" % (db, table), 'r', encoding='utf-8')
264 
265      filter_res=where_action(fh,sql_dic.get('where'))
266      fh.close()
267 
268      limit_res=limit_action(filter_res,sql_dic.get('limit'))
269      search_res=search_action(limit_res,sql_dic.get('select'))
270      return search_res
271 
272 
273 
274 def where_action(fh,where_l):
275     res=[]
276     logic_l=['and','or','not']
277     title="id,name,age,phone,dept,enroll_date"
278     if len(where_l) !=0:
279         for line in fh:
280             dic=dict(zip(title.split(','),line.split(',')))
281             logic_res=logic_action(dic,where_l)
282             if logic_res:
283                 res.append(line.split(','))
284     else:
285         res=fh.readlines()
286     return res
287 
288 def logic_action(dic,where_l):
289     res=[]
290     # print('==\033[45;1m%s\033[0m==\033[48;1m%s\033[0m' %(dic,where_l))
291     for exp in where_l:
292         if type(exp) is list:
293             exp_k,opt,exp_v=exp
294             if exp[1] == '=':
295                 opt='%s=' %exp[1]
296             if dic[exp_k].isdigit():
297                 dic_v=int(dic[exp_k])
298                 exp_v=int(exp_v)
299             else:
300                 dic_v="'%s'" %dic[exp_k]
301             if opt != 'like':
302                 exp=str(eval("%s%s%s" %(dic_v,opt,exp_v)))
303             else:
304                 if exp_v in dic_v:
305                     exp='True'
306                 else:
307                     exp='False'
308         res.append(exp)
309     res=eval(' '.join(res))
310     # print('==\033[45;1m%s\033[0m' %(res))
311     return res
312 
313 def limit_action(filter_res,limit_l):
314     res=[]
315     if len(limit_l) !=0:
316         index=int(limit_l[0])
317         res=filter_res[0:index]
318     else:
319         res=filter_res
320 
321     return res
322 
323 def search_action(limit_res,select_l):
324     res=[]
325     fileds_l=[]
326     title="id,name,age,phone,dept,enroll_date"
327     if select_l[0] == '*':
328         res=limit_res
329         fileds_l=title.split(',')
330     else:
331 
332         for record in limit_res:
333             dic=dict(zip(title.split(','),record))
334             # print("dic is %s " %dic)
335             fileds_l=select_l[0].split(',')
336             r_l=[]
337             for i in fileds_l:
338                 r_l.append(dic[i].strip())
339             res.append(r_l)
340 
341     return [fileds_l,res]
342 
343 def help():
344     msg = '''
345                        =_= 歡迎使用員工信息系統 =_=
346     本系統支持基本SQL語句查詢,資料庫為db,用戶表名為user,必須使用列出的SQL語句操作,否則會出現未知錯誤
347     例:
348     查詢: select * from db.user where name like 李 and id > 10
349            select name,id from db.user where id > 10 or age < 30
350     增加:  insert into db.user values Eric,22,17233786749,運維,2012-01-10
351     修改:  update db.user set age=24 where name like 李強
352            update db.user set dept=IT where name like 李強
353     刪除:  delete from db.emp where id = 26
354     退出: exit()
355     幫助: help
356         '''
357     print(msg)
358 if __name__ == '__main__':
359     help()
360     while True:
361         sql=input("sql> ").strip()
362         if sql == 'exit':break
363         if sql == 'help': help()
364         if len(sql) == 0:continue
365 
366         sql_dic=sql_parse(sql)
367 
368         if len(sql_dic) == 0:continue
369         res=sql_action(sql_dic)
370 
371         for i in res[-1]:
372             print(i)
View Code

 

 

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.面向對象都有哪些特性 繼承、封裝、多態性、抽象 2.Java中實現多態的機制是什麼? 繼承與介面 3.Java中異常分為哪些種類 3.1按照異常需要處理的時機分為編譯時異常(CheckedException)和運行時異常(RuntimeException)。 3.2對於編譯時異常的處理方法有兩種 ...
  • 右鍵項目-》屬性-》java bulid path-》jre System Library-》access rules-》resolution選擇accessible,下麵填上** 點擊確定即可!!! 如下圖: ...
  • 安裝與使用 1. 以2.7.6為例 安裝路徑:D:\Program Files (x86)\Python27\安裝完成後打開軟體,如果提示:‘python’不是內部或外部命令,也不是可運行的程式或批處理文件。 需要手動添加環境變數。 2. 兩種運行模式 命令行模式 (1) 使用notepad++ 編 ...
  • 1 from bs4 import BeautifulSoup 2 import requests 3 from random import choice 4 import csv 5 6 headers1 = {'User-Agent':'spider'} 7 headers2 = {'User-... ...
  • 轉換流 1、轉換流:將位元組流轉換成字元流,轉換之後就可以一個字元一個字元的往程式寫內容了,並且可以調用字元節點流的write(String s)方法,還可以在外面套用BufferedReader()和BufferedWriter,並使用它們的readLine 和 newLine方法。 2、有兩種轉換 ...
  • <?php//生成隨機數 和 時間函數//echo rand();//echo "<br>";//echo rand(0,10);//echo time();//時間戳//2017-02-10 08:46:12date_default_timezone_set("Asia/Shanghai");// ...
  • 總結一下對象的創建過程,假設有一個名為Dog的類: 1. 即使沒有顯示地使用static關鍵字,構造器實際上也是靜態的方法,因此,當首次創建類型為Dog的對象時(構造器可以看成靜態方法),或者Dog類的靜態方法/靜態域首次被訪問時,java解釋器必須查找類的路徑,以定位Dog.class文件。 2. ...
  • Redisson分散式鎖 之前的基於註解的鎖有一種鎖是基本redis的分散式鎖,鎖的實現我是基於redisson組件提供的RLock,這篇來看看redisson是如何實現鎖的。 不同版本實現鎖的機制並不相同 引用的redisson最近發佈的版本3.2.3,不同的版本可能實現鎖的機制並不相同,早期版本 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...