引言

个人平时在写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. mysql数据库字段内容替换

    UPDATE 表名 SET 字段名= replace(字段名, '查找内容', '替换成内容') ; UPDATE car_articles SET article_title = replace(a ...

  2. vue踩坑(一):打包上线

    找到config→index.js 然后找到index.js的buildassetsPublicPath  这个修改为你的项目放在服务器的路径 像我的项目是放在wap 文件夹下的 这些配置完成后然后 ...

  3. 无监督学习算法-Apriori进行关联分析

    关联分析 是无监督讯息算法中的一种,Apriori主要用来做_关联分析_,_关联分析_可以有两种形式:频繁项集或者关联规则.举个例子:交易订单 序号 商品名称 1 书籍,电脑 2 杯子,手机,手机壳, ...

  4. 第一个用IDEA写的程序——“前言中不允许有内容”

    "前言中不允许有内容" 这是用IDEA写的第一个程序-- 它出现了一些问题 让人很难过 希望有人可以帮助解答,谢谢 程序是这样子的 运行完是这样显示的

  5. centos 7 vim 保存文件 root 权限 及 使用

    vim打开文件时,没有用root账户,保存时才发现需要root权限.办法是在vim执行一下命令: :w !sudo tee % 未完待续

  6. 使用U盘安装CentOS7

    为了在公司的旧笔记本电脑上安装centos供自己学习使用折腾了两天,终于在看了https://www.cnblogs.com/yeeo1/p/7306611.html这篇博文后装上了, 以下内容为转载 ...

  7. Java 7 使用TWR(Try-with-resources)完成文件copy

    try-with-resources语句是声明了一个或多个资源的try语句块.在java中资源作为一个对象,在程序完成后必须关闭.try-with-resources语句确保每个资源在语句结束时关闭. ...

  8. UVA 2451 Brackets sequence

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=9 ...

  9. 【mysql】decimal数据类型

    1.float.double.decimal float:浮点型,4字节,32bit. double:双精度实型,8字节,64位 decimal:数字型,128bit,不存在精度损失,常用于银行帐目计 ...

  10. Java8特性之Lambda、方法引用和Streams

    这里涉及三个重要特性: Lambda 方法引用 Streams ① Lambda 最早了解Lambda是在C#中,而从Java8开始,Lambda也成为了新的特性,而这个新的特性的目的,就是为了消除单 ...