Sequel Pro 实现更好的 SQL 格式化

7,287 阅读3分钟
原文链接: mp.weixin.qq.com

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

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

自带格式化功能入口

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

修正自带 Bundle

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

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

  • 打开菜单 Bundles->BundleEditor

  • 左边栏选择 Inputfield (Show) -> Format (Show) -> FormatSQL (Show)

  • 在 "Command" 区域找到这行代码 <inputtype="hidden"name="clientid"value="..."/>

  • 把这个 input 的 value 改为 dpriver-9094-8133-2031

  • 保存

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

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

自己动手

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

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

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

打开 Bundle 编辑器

按菜单 Bundles -> BundleEditor 打开编辑器

创建 Bundle

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

配置 Bundle

注意将 OutPut 项更改为 ReplaceSelection,然后在 Command 部分贴入以下代码:

    #!/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

格式化之后:

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

  • https://sqlformat.org/api/

附 PHP 版代码,效果一致:

    #!/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

参考

  • Update SQL formatter bundle for new API

  • SQLFormat