python查询sql_Python处理SQL语句(提供SQL查询平台使用)
在搞公司的SQL查詢(MySQL)平臺時,需要對用戶查詢SQL進行條數限制,默認是在配置文件中配置一個“limit = 1000”這樣的參數。最自然想到的就是對用戶通過web傳入的SQL做處理,默認加上limit參數。這樣一來就有這么幾個問題需要處理:
1. 如果用戶自己傳入了limit 10這樣的條件怎么辦?
2. 如果用戶自己傳入了limit 10,2這樣的條件怎么辦?
3. 如果用戶的查詢比較復雜,有多個子查詢并帶有limit怎么辦?
4. 如果用戶查詢字段有`limit`(不加“時的SQL會報語法錯誤)、及表名有limit這樣的關鍵字怎么辦?
測試通過代碼如下,提供一個處理函數:
import json
import re
def replace_limit(sql, limit):
"""
依次查找并處理limit offset,然后把limit關鍵字替換為special_flag
全部處理完后再把special_flag替換回limit
:param sql:
:param limit:
:return:
"""
special_flag = '-*-*-'
def fun(new_sql):
"""
:return: sql
"""
upper_sql = new_sql.upper()
start_index = upper_sql.find(' LIMIT ') + len(' LIMIT ')
end_index = start_index
for i in range(start_index, len(upper_sql)):
if bool(re.match(r'^[0-9]|,| ', upper_sql[i])):
end_index += 1
else:
break
limit_str = upper_sql[start_index:end_index].strip()
# 輸入limit值大于默認limit值就進行替換成默認limit值
if ',' in limit_str:
offsets = limit_str.split(',')
if int(offsets[-1]) > limit:
limit_str = '{}, {}'.format(offsets[0], limit)
else:
if int(limit_str) > limit:
limit_str = '{}'.format(limit)
limit_str = ' ' + limit_str + ' '
new_sql = new_sql.replace(
new_sql[start_index:end_index], limit_str, 1
)
new_sql = new_sql.replace(
new_sql[start_index - len(' LIMIT '):start_index], special_flag, 1
)
return new_sql
# 原sql沒有limit則在最后加上limit,并return
if re.search(r'limit\s.*\d.*', sql, re.IGNORECASE) is None:
sql = sql.rstrip(';') + ' limit %s' % int(limit) + ';'
return sql
# 分析limit語句
for i in re.findall(' limit ', sql, re.IGNORECASE):
sql = fun(sql)
# 替換回limit關鍵字
sql = sql.replace(special_flag, ' limit ')
return sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
importjson
importre
defreplace_limit(sql,limit):
"""
依次查找并處理limitoffset,然后把limit關鍵字替換為special_flag
全部處理完后再把special_flag替換回limit
:paramsql:
:paramlimit:
:return:
"""
special_flag='-*-*-'
deffun(new_sql):
"""
:return:sql
"""
upper_sql=new_sql.upper()
start_index=upper_sql.find(' LIMIT ')+len(' LIMIT ')
end_index=start_index
foriinrange(start_index,len(upper_sql)):
ifbool(re.match(r'^[0-9]|,| ',upper_sql[i])):
end_index+=1
else:
break
limit_str=upper_sql[start_index:end_index].strip()
# 輸入limit值大于默認limit值就進行替換成默認limit值
if','inlimit_str:
offsets=limit_str.split(',')
ifint(offsets[-1])>limit:
limit_str='{}, {}'.format(offsets[0],limit)
else:
ifint(limit_str)>limit:
limit_str='{}'.format(limit)
limit_str=' '+limit_str+' '
new_sql=new_sql.replace(
new_sql[start_index:end_index],limit_str,1
)
new_sql=new_sql.replace(
new_sql[start_index-len(' LIMIT '):start_index],special_flag,1
)
returnnew_sql
# 原sql沒有limit則在最后加上limit,并return
ifre.search(r'limit\s.*\d.*',sql,re.IGNORECASE)isNone:
sql=sql.rstrip(';')+' limit %s'%int(limit)+';'
returnsql
# 分析limit語句
foriinre.findall(' limit ',sql,re.IGNORECASE):
sql=fun(sql)
# 替換回limit關鍵字
sql=sql.replace(special_flag,' limit ')
returnsql
這個函數接收兩個參數,SQL語句和默認limit限制值,在平臺中是SQL是從前端獲取來的,limit值是從配置文件獲取來的。
大概邏輯如下:
1. 如果字段中有`limit`或limittest關鍵字就不需要處理。
2. 如果用戶輸入沒有limit限制就加上默認limit限制,然后直接返回sql。
3. 如果用戶輸入有limit限制就進行判斷用戶輸入值是否大于默認值,如果大于就替換成默認值,否則不改動。
4. 最后把替換過的關鍵字再替換回來。
在這里測試,就可以直接調用函數即可,如下:
sql = "select limitest as `limit` from test limit 10, 100;"
print(replace_limit(sql, 20))
1
2
sql="select limitest as `limit` from test limit 10, 100;"
print(replace_limit(sql,20))
結果如下:
select limitest as `limit` from test limit 10, 20;
1
selectlimitestas`limit`fromtestlimit10,20;
可以看到結果滿足我們的需求,由于用戶輸入值大于默認值就替換成了默認limit值。
如果您覺得本站對你有幫助,那么可以支付寶掃碼捐助以幫助本站更好地發展,在此謝過。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的python查询sql_Python处理SQL语句(提供SQL查询平台使用)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一般速冻饺子煮几分钟 多久能煮熟速冻饺子
- 下一篇: x浏览器和via浏览器对比(Wikipe