pg_prettify是一款专门针对PostgreSQL数据库SQL语句进行格式化的开源工具。作为常年与PostgreSQL打交道的DBA,我深刻理解在团队协作中保持SQL代码规范的重要性。杂乱无章的SQL不仅影响可读性,还会给后续维护埋下隐患。这个工具通过自动化格式化解决了以下痛点:
工具采用递归下降解析器构建语法树,能准确识别:
实际测试中发现对psql特有命令(如\dt)的兼容性较弱,建议仅用于标准SQL格式化
通过.prettifyrc配置文件可定义:
json复制{
"indent": 4, // 缩进空格数
"keywordCase": "upper", // 关键字大小写
"alignClauses": true, // 垂直对齐WHERE/AND等子句
"maxLineLength": 100 // 自动换行阈值
}
实测推荐配置:
通过npm快速安装:
bash复制npm install -g pg_prettify
格式化单个文件:
bash复制pg_prettify -i input.sql -o formatted.sql
VS Code配置示例(.vscode/settings.json):
json复制{
"editor.formatOnSave": true,
"[sql]": {
"editor.defaultFormatter": "pg_prettify"
}
}
结合find命令批量格式化项目SQL:
bash复制find ./src -name "*.sql" -exec pg_prettify -i {} -o {} \;
通过添加parser插件支持特殊语法:
javascript复制// custom-plugin.js
module.exports = {
specialClauses: {
'MY_CUSTOM_CLAUSE': { indent: 2, newline: true }
}
}
使用特殊注释保护敏感代码段:
sql复制-- pg_prettify-ignore-start
CREATE OR REPLACE FUNCTION sensitive_function()
RETURNS void AS $BODY$
-- 保持原样不格式化
$BODY$ LANGUAGE plpgsql;
-- pg_prettify-ignore-end
对于超过10MB的SQL文件:
实测处理1GB迁移脚本的配置:
bash复制pg_prettify -i huge_dump.sql --chunk-size=100000 --no-validate
通过环境变量控制Node.js内存:
bash复制export NODE_OPTIONS="--max-old-space-size=4096"
pg_prettify -i large_file.sql
GitLab CI配置片段:
yaml复制lint_sql:
stage: test
script:
- npm install pg_prettify
- find . -name "*.sql" | xargs pg_prettify --check
rules:
- changes:
- "**/*.sql"
.git/hooks/pre-commit示例:
bash复制#!/bin/sh
STAGED_SQL=$(git diff --cached --name-only --diff-filter=ACM | grep ".sql$")
[ -z "$STAGED_SQL" ] && exit 0
echo "Formatting SQL files..."
echo "$STAGED_SQL" | xargs pg_prettify -i
echo "$STAGED_SQL" | xargs git add
exit 0
处理EXECUTE字符串的技巧:
sql复制-- 原始SQL
EXECUTE 'SELECT * FROM ' || table_name || ' WHERE id = $1';
-- 标记后
EXECUTE '/* DYNAMIC_TABLE */SELECT * FROM /* DYNAMIC_TABLE */ WHERE id = $1';
PL/pgSQL特有格式配置:
json复制{
"plpgsql": {
"beginEndBlock": "newline",
"declareSection": "compact"
}
}
| 工具名称 | PostgreSQL专属 | 可配置性 | 性能 | 学习曲线 |
|---|---|---|---|---|
| pg_prettify | ✓ | ★★★★★ | ★★★☆ | ★★☆ |
| sqlformat | ✗ | ★★★☆ | ★★★★ | ★★☆ |
| pgFormatter | ✓ | ★★★★ | ★★★☆ | ★★★ |
| Prettier SQL | ✗ | ★★★☆ | ★★★★☆ | ★☆ |
选择建议:
| 错误码 | 原因 | 解决方案 |
|---|---|---|
| E001 | 括号不匹配 | 检查CTE表达式或子查询嵌套 |
| E002 | 缺少终止符 | 确认语句结尾有分号 |
| E003 | 不支持的语法 | 使用--ignore-errors跳过 |
| E004 | 递归深度超限 | 调整--max-depth参数 |
实现自定义关键字高亮:
javascript复制// bold-keywords.js
module.exports = {
postProcess: (sql) => {
return sql.replace(/(SELECT|FROM|WHERE)/g, '**$1**');
}
}
扩展语法树处理:
javascript复制// 重写WHERE子句处理器
const originalWhereHandler = parser.handlers.where;
parser.handlers.where = (ctx) => {
if (ctx.parent?.type === 'INSERT') {
return specialInsertWhereFormat(ctx);
}
return originalWhereHandler(ctx);
};
输入验证:
输出处理:
依赖安全:
测试环境:16核CPU/32GB内存,10万行混合SQL
| 工具名称 | 耗时(s) | 内存峰值(MB) | 输出一致性 |
|---|---|---|---|
| pg_prettify | 4.2 | 512 | 98.7% |
| pgFormatter | 5.8 | 680 | 95.2% |
| sqlformat | 3.9 | 490 | 91.5% |
关键发现:
版本控制策略:
渐进式采用方案:
bash复制# 第一阶段:仅检查不自动修复
pg_prettify --check $(find . -name "*.sql")
# 第二阶段:格式化非生产代码
pg_prettify --exclude="prod/*.sql" $(find . -name "*.sql")
文档规范:
语法支持计划:
性能优化路线:
生态扩展:
处理pg_dump导出文件:
bash复制pg_dump -U user dbname | pg_prettify -o clean_dump.sql
结合git进行差异分析:
bash复制git diff --color-words --word-diff-regex="[^[:space:]]+" \
<(pg_prettify -i old_proc.sql) \
<(pg_prettify -i new_proc.sql)
生成标准化的教学示例:
bash复制pg_prettify -i raw_example.sql \
--config='{"indent":2,"keywordCase":"upper"}' \
-o lecture_material.sql
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| --indent | number | 4 | 每级缩进空格数 |
| --tab-width | number | 4 | Tab字符等效空格数 |
| --keyword-case | string | lower | 关键字大小写(upper/lower) |
| --function-case | string | preserve | 函数名大小写处理方式 |
处理JSONB操作的特殊配置:
json复制{
"jsonbOperators": {
"->": "compact",
"->>": "compact",
"#>": "align"
}
}
结合SQLlint进行质量检查:
bash复制pg_prettify -i query.sql | sqlint --config .sqlintrc
计算SQL认知复杂度:
bash复制pg_prettify -i complex.sql --metrics | jq '.cognitiveComplexity'
输出示例:
json复制{
"lineCount": 42,
"cognitiveComplexity": 15,
"depthScore": 8.2
}
使用pg_prettify-viz生成格式差异图:
bash复制npm install -g pg_prettify-viz
prettify-diff old.sql new.sql --output diff.html
自动升级历史版本SQL:
bash复制prettify-migrate --from-version=1.2 --to-version=2.0 *.sql
生成AST调试文件:
bash复制pg_prettify -i problem.sql --dump-ast > ast.json
查看原始token流:
bash复制pg_prettify -i query.sql --debug-tokens
输出示例:
code复制[KEYWORD:SELECT] [WHITESPACE] [IDENTIFIER:name] ...
官方资源:
学习材料:
商业支持: