写 SQL 总觉得像在念咒语?PRQL 或许是你一直在找的"人类友好版 SQL"。
在数据驱动的时代,SQL 依然是我们与数据库对话的通用语言。但不可否认,SQL 的语法设计早已跟不上现代开发体验的需求:关键字顺序反直觉、嵌套难以阅读、逻辑无法复用......尤其当查询变得复杂时,维护一段 SQL 几乎成了一种"考古工作"。
有没有一种方式,既能保留 SQL 的强大能力,又能让查询像代码一样清晰、模块化、易测试?
答案是:PRQL(Pipelined Relational Query Language)。
什么是 PRQL?
PRQL 是一种现代、声明式、管道化的查询语言 ,目标是成为 SQL 的"更好替代品"。它由 Rust 编写,最终编译为标准 SQL,可在任何支持 SQL 的数据库(PostgreSQL、MySQL、BigQuery、Snowflake 等)上运行。
它的核心理念是:让数据查询像写函数一样自然。
一个简单对比
传统 SQL:
sql
SELECT name, salary
FROM employees
WHERE start_date > '2020-01-01'
ORDER BY salary DESC
LIMIT 10;
PRQL 写法:
prql
from employees
filter start_date > @2020-01-01
select {name, salary}
sort {-salary} # 负号表示降序
take 10
是不是更像你在"描述操作步骤"?从 from 开始,一步步过滤、选择、排序、截取------自上而下,符合人类思维流。
为什么 PRQL 值得关注?
✅ 1. 管道式语法,逻辑清晰
使用 |> 风格的隐式管道(虽然不写符号),每个操作按顺序执行,避免 SQL 中 SELECT 在前、FROM 在后的认知负担。
✅ 2. 可组合、可复用
你可以把一段 PRQL 逻辑提取为"子查询",并在多处调用(虽然目前需手动内联,但结构天然支持模块化)。
✅ 3. 编译时检查
PRQL 编译器能提前发现字段不存在、类型不匹配等问题,减少运行时错误。
✅ 4. 跨数据库兼容
PRQL 编译出的是标准 SQL,自动适配目标数据库方言(未来会进一步增强)。
✅ 5. 多语言支持
官方提供 Python、JavaScript/TypeScript、Rust 绑定,轻松集成到你的技术栈中。
实战:在 Python 中使用 PRQL 实现分页 API
假设你正在开发一个员工管理系统,需要支持分页查询。
第一步:安装 PRQL Python 包
bash
pip install prql-python
第二步:编写动态分页查询
python
from prql_python import compile
def build_employee_query(page: int, page_size: int, min_salary: float = 0):
skip = (page - 1) * page_size
prql = f"""
from employees
filter salary >= {min_salary}
select {{id, name, salary, department}}
sort {{-salary}} # 高薪优先
skip {skip}
take {page_size}
"""
return compile(prql)
# 使用示例
sql = build_employee_query(page=2, page_size=10, min_salary=5000)
print(sql)
输出(PostgreSQL 风格):
sql
SELECT "id", "name", "salary", "department"
FROM "employees"
WHERE "salary" >= 5000
ORDER BY "salary" DESC
OFFSET 10
LIMIT 10
第三步:集成到 FastAPI / Flask
你可以在 Web 框架中直接返回编译后的 SQL,或结合 SQLAlchemy 执行,实现安全、动态的查询接口。
💡 安全提示:虽然这里用了 f-string,但
skip、take、min_salary均为数值类型,不会导致 SQL 注入。若涉及字符串,仍需使用参数化查询。
适用场景推荐
| 场景 | PRQL 优势 |
|---|---|
| 数据分析探索 | 快速迭代,逻辑清晰 |
| ETL 脚本 | 减少嵌套,提升可维护性 |
| BI 报表底层查询 | 更易审查和协作 |
| 教学/团队规范 | 降低 SQL 学习门槛 |
| 动态查询构建 | 比字符串拼接更安全可靠 |
当前局限与注意事项
- 不支持数据库特有函数 :如 PostgreSQL 的
JSONB操作,需 fallback 到原生 SQL。 - 无变量系统:不能在 PRQL 内部定义变量,需在宿主语言处理。
- Java 暂无官方库 :可通过命令行工具
prqlc间接调用。 - 深度分页性能 :和 SQL 一样,
skip大偏移量效率低,建议用游标分页(基于 ID 过滤)。
如何开始?
-
在线体验 :PRQL Playground
-
安装 CLI 工具 :
bash# macOS/Linux curl -L https://github.com/PRQL/prql/releases/latest/download/prql-x86_64-unknown-linux-gnu.tar.gz | tar xz ./prqlc --help -
集成到项目 :
- Python:
pip install prql-python - Node.js:
npm install prql-js
- Python:
结语
PRQL 不是要"取代 SQL",而是让 SQL 更好用。它站在巨人的肩膀上,用现代语言设计思想重新思考"如何表达数据查询"。
如果你厌倦了调试三层嵌套的 SQL,或者希望团队的查询逻辑更易读、更可维护,现在就是尝试 PRQL 的最佳时机。
让数据查询回归本质:清晰地表达"我要什么",而不是纠结"怎么写才合法"。
延伸阅读