引言

个人平时在写sql脚本的时候会使用到SQL Prompt这款插件,除了强大的智能提示和格式化sql语句功能,我还喜欢使用Snippets代码段功能。比如我们可以在查下分析器输入ssf后按Tab键,SQL Prompt就可以帮我们快速的输入SELECT  * FROM 。

但是个人不习惯看大写的sql代码,所以就想捣鼓着将代码段输出的代码变成小写。打开代码段管理界面,发现管理工具提供了编辑代码段的功能,但是如果要一个个的编辑,自行转换成小写,再保存,那显然不是咱的风格。可以看到SQL Prompt存放代码段的路径:

找到路径中的文件打开可以看到,代码段文件是一个扩展名为sqlpromptsnippet的xml文件。

所以想着使用python来批量的将代码段文件中的代码转换成小写。

一. xml操作——找到Code节点并获取代码段的sql语句

1. xml格式文件节点类型详细介绍可以参考   W3School教程

2. python中读写xml文件可以使用mxl.dom.minidom模块,查找Code节点代码如下:

import xml.dom.minidom

snippet = xml.dom.minidom.parse('ssf.sqlpromptsnippet')
root = snippet.documentElement
print(root.nodeType,root.nodeName,root.nodeValue) code = snippet.getElementsByTagName('Code')[0]
print(code.nodeType,code.nodeName,code.nodeValue)

snippet = xml.dom.minidom.parse('ssf.sqlpromptsnippet') :表示打开当前路径中名为'ssf.sqlpromptsnippet'的xml文件,并把xml文件对象赋值给snippet对象。

root = snippet.documentElement :表示获取snippet对象的文档元素(根节点),并把获得的对象给root。

code = snippet.getElementsByTagName('Code')[0]  :表示查找root根节点下面所有名为Code的子元素,并将第一个子元素赋值给code对象。

执行结果:

1 CodeSnippets None
1 Code None

因为CodeSnippets和Code节点都不是文本节点,所有其nodeValue属性为None。Code节点为1CDATASection节点,其有以下属性:

所以找到Code节点并获取代码段的sql语句的正确语句如下:

import xml.dom.minidom

snippet = xml.dom.minidom.parse('ssf.sqlpromptsnippet')
root = snippet.documentElement
#print(root.nodeType,root.nodeName,root.nodeValue)
code = snippet.getElementsByTagName('Code')[0]
#print(code.nodeType,code.nodeName,code.nodeValue)
statement = code.firstChild.data # code的第1个(也是唯一的)子元素才是CDATASection节点
print (statement)

执行结果:

SELECT * FROM

二. sql代码转换操作——大写转小写

1. sql语句大写转小写,可以直接使用str类的lower函数即可:

statementlower = statement.lower()
print (statementlower)

执行结果:

select * from

2. SQL Prompt中有部分代码段是含有占位符的,占位符的格式为”$CURSOR$”,而且其是区分大小写的,所以占位符不能转换成小写。所以需要先将代码段中个sql语句中的占位符全部找出来,并存储起来,在sql语句转换成小写之后替换回去。

因为占位符都是以“$”开头,也以“$”结尾,所以我们可以很方便的使用正则表达式来查找sql语句中的所有占位符。查找出来之后先将占位符和其小写形式使用dict存储起来。

import xml.dom.minidom
import re snippet = xml.dom.minidom.parse('ct.sqlpromptsnippet')
root = snippet.documentElement
#print(root.nodeType,root.nodeName,root.nodeValue)
code = snippet.getElementsByTagName('Code')[0]
#print(code.nodeType,code.nodeName,code.nodeValue)
statement = code.firstChild.data # code的第1个(也是唯一的)子元素才是CDATASection节点print (statement)
print (statement) # 输出原语句 # 正则查找所有的占位符
keylist = re.findall("\$\w+\$",statement)
# 将占位符和其小写形式存储成字典
placeholds = dict()
for key in keylist:
placeholds[key] = key.lower() print(placeholds) # 先将语句转换成小写
statementlower = statement.lower() # 循环占位符字典,替换回占位符
for k,v in placeholds.items():
statementlower = statementlower.replace(v,k) print (statementlower)

执行结果:

CREATE TABLE $table_name$
(
$CURSOR$
)
{'$table_name$': '$table_name$', '$CURSOR$': '$cursor$'}
create table $table_name$
(
$CURSOR$
)

三. xml操作——将转换代码写回xml文件

xml写操作使用的是writexml文件,具体代码如下:

import xml.dom.minidom
import re snippet = xml.dom.minidom.parse('ct.sqlpromptsnippet')
root = snippet.documentElement
#print(root.nodeType,root.nodeName,root.nodeValue)
code = snippet.getElementsByTagName('Code')[0]
#print(code.nodeType,code.nodeName,code.nodeValue)
statement = code.firstChild.data # code的第1个(也是唯一的)子元素才是CDATASection节点print (statement)
keylist = re.findall("\$\w+\$",statement)
placeholds = dict()
for key in keylist:
placeholds[key] = key.lower() statementlower = statement.lower() for k,v in placeholds.items():
statementlower = statementlower.replace(v,k) #更新XML对象
code.firstChild.data = statementlower # 打开文件对象,再写入
f = open('result\ct.sqlpromptsnippet', 'w',encoding = 'utf-8')
snippet.writexml(f, addindent='', newl='',encoding='utf-8')
f.close()

执行结果生成文件对比:

四. 批量操作——循环代码段文件批量处理

1.  循环目录下的文件,使用的是os模块的listdir方法。

>>> import os
>>> os.listdir()
['DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'NEWS.txt', 'python.exe', 'python3.dll', 'python35.dll', 'pythonw.exe', 'README.txt', 'Scripts', 'tcl', 'Tools', 'vcruntime140.dll']

2. 先将单个转换封装成方法sqllower,再循环读取目录下的代码段文件即可完成批量处理,完整代码如下:

import xml.dom.minidom
import re
import os def sqllower(name):
snippet = xml.dom.minidom.parse(name)
root = snippet.documentElement
#print(root.nodeType,root.nodeName,root.nodeValue)
code = snippet.getElementsByTagName('Code')[0]
#print(code.nodeType,code.nodeName,code.nodeValue)
statement = code.firstChild.data # code的第1个(也是唯一的)子元素才是CDATASection节点print (statement)
#print (statement) keylist = re.findall("\$\w+\$",statement)
placeholds = dict()
for key in keylist:
placeholds[key] = key.lower() #print(placeholds)
statementlower = statement.lower() for k,v in placeholds.items():
statementlower = statementlower.replace(v,k) #print (statementlower) #更新XML对象
code.firstChild.data = statementlower f = open('result\\' + name, 'w',encoding = 'utf-8')
snippet.writexml(f, addindent='', newl='',encoding='utf-8')
f.close() # 循环进行转换
for f in os.listdir():
if f.endswith('.sqlpromptsnippet'):
print('正在转换'+ f)
sqllower(f) print ('所有转换完成。')

五. 总结

本文从日常使用中提取出sql代码段大小写转换的需求,将其使用Python实现。使用到了如下的模块:

1. xml.dom.minidom模块,用来读写xml文件。

2. re模块,使用了正则表达式,查询所有的占位符。

3. os模块,使用listdir方法来循环目录中个文件。

Python日常实践(1)——SQL Prompt的Snippets批量整理的更多相关文章

  1. SQL Prompt snippets

    SQL    Prompt snippets https://github.com/gvohra/sqlpromptsnippets

  2. SQL Prompt——SQL智能提示插件

    数据库是大家在项目开发中肯定会用到的,C#项目用的最多的就是微软自家的SQL Server了.不可否认,微软的Visual Studio开发平台很好用,很直观的体现就是智能提示.敲几个字符,相关的信息 ...

  3. SSMS开发利器Sql Prompt

    一.前言 一个Sql Server 开发智能提示插件,方便查询表结果,避免了开发人员一个个敲查询语句.执行语句等,一起来看看吧. SQL Prompt 9.5 支持SSMS18 下载地址: 链接:ht ...

  4. python 使用pymssql连接sql server数据库

    python 使用pymssql连接sql server数据库   #coding=utf-8 #!/usr/bin/env python#------------------------------ ...

  5. sql prompt 安装使用教程

    sql prompt:和vs的自动提示一样 数据库:2008r2 下载地址:http://download.csdn.net/detail/wozengcong/9048381 安装教程:http:/ ...

  6. 如何 在远程虚拟机 里 破解 最新版 SQL Prompt

    玩数据的人 经常 写写 SQL,SQL Prompt 是蛮好用的 辅助工具 ,现在 的 主流 破解工具 都是 需要  断开网路的 但是 现在 有些  开发环境 都是 在 云虚拟机 里,比如 客户方的. ...

  7. python日常-list and dict

    什么是list: list 觉得算是python日常编程中用的最多的python自带的数据结构了.但是python重的list跟其他语言中的并不相同. 少年..不知道你听说过python中的appen ...

  8. SQL Prompt激活

    SQL脚本越写越多,总是觉得编写效率太过于低下,这和打字速度无关.在我个人编写SQL脚本时,至少会把SQL的格式排列成易于阅读的,因为其他人会阅读到你的SQL,无论是在程序中或是脚本文件中,良好的排版 ...

  9. SQL Prompt

    SQL Prompt介绍编辑 SQL Prompt[1] 是一款拥有SQL智能提示功能的SQL Server和VS插件.SQL Prompt能根据数据库的对象名称,语法和用户编写的代码片段自动进行检索 ...

随机推荐

  1. FortiGate数据流分析 debug flow

    1.工具说明 在防火墙部署中,经常会遇到防火墙接收到了数据包,但并未进行转发.可以通过diagnose debug flow 命令来对数据包的处理过程进行跟踪,可以清晰查看数据包再各个功能模块内的处理 ...

  2. swift - UIButton按钮有图片是点击高亮 有灰色动画

    取消 高亮的 动画 btn.adjustsImageWhenHighlighted = false btn.layer.removeAllAnimations()

  3. [leetcode]53. Maximum Subarray最大子数组和

    Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...

  4. Django自动获取项目中的全部URL

    import re from collections import OrderedDict from django.conf import settings from django.utils.mod ...

  5. 二、putty的下载安装和基本使用方法教程

    转载自:https://baijiahao.baidu.com/s?id=1597811787635071952&wfr=spider&for=pc PuTTY是一款开源(Open S ...

  6. ps高级磨皮的7个步骤

    1.打开图片 2. 进入通道看红绿蓝哪个通道痘比较明显拖拽复制拷贝哪个通道! 3.选中拷贝的通道--执行滤镜--其他--高反差保留 4.在执行图像--计算(混合模式强光)--计算三次 5.选alpha ...

  7. 【APP测试(Android)】--用户体验

  8. s5-6 Linux 标准输出 系统优化 目录结构

    标准输出 重定向符号 #>   1>    标准输出重定向  先把文件的内容清空   把内容放在文件的最后一行 #>>  1>>   追加重定向      把内容放 ...

  9. hdu 1325 && poj 1308 Is It A Tree?(并查集)

    Description A tree is a well-known data structure that is either empty (null, void, nothing) or is a ...

  10. Javascript上传超大文件实例

    因业务需求需要向伺服器上传大于1GB以上的视频文件,其实网上也能找到很多大文件上传的第三方组件,问题是要么用起来相当不方便,总出现一些bug,要么收费太贵(费用几千,甚至还限定使用数量),最终自己开发 ...