让 Mac 上的数据库管理客户端 Sequel Pro 有更好的 SQL 格式化功能。

说起 Mac 上的数据库管理 App,靠谱的可选项并不多,除了 Win 平台同样有的老牌全功能客户端 Navicat,仅有 Sequel Pro、SQLPro Studio 等几个轻量的选择以及官方的 Workbench 和发布不久的 DataGrip。

在工具的选择上一向偏爱简洁够用就好,最初用 Mac 时反复比较了多个可选项最终选择了开源的 Sequel Pro 作为首选客户端,和之前在 Win 上主要用的 SQLyog 相比,界面操作之类的都可以习惯,唯独 SQL 格式化功能始终不能忍受。

自带格式化功能入口

Sequel Pro 的 SQL 格式化功能以 Bundle 也就是插件的形式提供,使用菜单 Bundles->Input Field->Format->Format SQL 执行。

14925125535553.jpg

修正自带 Bundle

官方版本自带的 Bundle 很可能无法开箱即用:

14925128749849.png

可以根据这个 Issue (https://github.com/sequelpro/sequelpro/issues/1988#issuecomment-60658598) 下的评论修正:

  • 打开菜单 Bundles -> Bundle Editor
  • 左边栏选择 Input field (Show) -> Format (Show) -> Format SQL (Show)
  • 在 “Command” 区域找到这行代码 <input type="hidden" name="clientid" value="..." />
  • 把这个 inputvalue 改为 dpriver-9094-8133-2031
  • 保存

这样修改后 SQL 格式化应该可以正常工作。


可以发现 Sequel Pro 提供的 SQL 格式化功能是以调用远程接口服务来实现的,并不是客户端内置的原生功能,使用时也需要联网。

自己动手

自带的 Bundle 修正之后基本功能没问题,但执行的时候不仅会弹出个调用远程接口的对话框,而且 SQL 的格式也不太令人满意。

除了 Sequel Pro 提供的 Bundle 所使用的 SQL格式化的服务外,还有其他类似的服务同样提供了可随意调用的 API,比如 sqlformat.org

这里就以 sqlformat.org 为例介绍一下如何创建一个比官方更好用的自定义 SQL 格式化 Bundle。

打开 Bundle 编辑器

按菜单 Bundles -> Bundle Editor 打开编辑器

14926890939691.jpg

创建 Bundle

将侧边菜单展开到 Input Field -> Format -> Format SQL,右键创建一个副本。

14926892176026.jpg

配置 Bundle

14926894425970.jpg

注意将 OutPut 项更改为 Replace Selection(这样调用远程接口时就不会弹窗),然后在 Command 部分贴入以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/python
#coding=utf-8
import urllib2, urllib
import json
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
sql = sys.stdin.read()
params = {'sql': sql, 'reindent': 1, 'keyword_case': 'upper', 'identifier_case': 'lower'}
response = urllib2.urlopen('https://sqlformat.org/api/v1/format', data=urllib.urlencode(params))
data = json.loads(response.read())
print data['result']

代码的功能就是调用了 sqlformat.org 的 API 并用格式化后的结果替换掉所选择的 SQL,代码贴完后 Save,从菜单里启用或者设置个快捷键看看效果吧。

这样一条 SQL:

1
SELECT TYPE, sum(CASE vender WHEN 'A' THEN pcs ELSE 0 END), sum(CASE vender WHEN 'C' THEN pcs ELSE 0 END), sum(CASE vender WHEN 'B' THEN pcs ELSE 0 END) FROM tablename t LEFT JOIN t1 ON t1.id = t.id LEFT JOIN t2 ON t2.id = t.id GROUP BY `type` ORDER BY t.create_time DESC HAVING t.cnt > 2

格式化之后:

14926907232365.jpg

sqlformat.org 的 API 文档里还有一些可选项可以设置,比如是否大写关键字、缩进宽度、是否移除注释等,可以参考文档修改代码参数。

附 PHP 版代码,效果一致:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/php
<?php
$sql = @file_get_contents("php://stdin");
$req = [
'reindent' => 1,
'sql' => $sql,
'keyword_case' => 'upper',
'identifier_case' => 'lower',
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://sqlformat.org/api/v1/format');
curl_setopt($ch, CURLOPT_POST, count($req));
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($req));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$ret = curl_exec($ch);
curl_close($ch);
echo json_decode($ret, true)['result'];

懒得折腾,下载打包好的 Bundle 直接导入即可:

http://newt0n.github.io/2017/04/14/Sequel-Pro-SQL-Formatter/Format-SQL-Py.spBundle.zip

参考

关注 NewtonIO - 创造者们的技术与工具