ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

PRQL 官方语言绑定全解析:Supported / Unsupported / Nascent 三级生态与 prqlc 核心 API 实践指南

PRQL 官方语言绑定全解析:Supported / Unsupported / Nascent 三级生态与 prqlc 核心 API 实践指南 PRQL 官方语言绑定全解析Supported / Unsupported / Nascent 三级生态与 prqlc 核心 API 实践指南【免费下载链接】prqlPRQL is a modern language for transforming data — a simple, powerful, pipelined SQL replacement项目地址: https://gitcode.com/gh_mirrors/pr/prql导读本文以 PRQL 仓库中 Bindings 索引文档 为骨架系统梳理 PRQL 编译器prqlc面向多语言生态的绑定策略与治理标准从 SupportedJavaScript、Python、R、Rust、UnsupportedJava、Elixir、C到 Nascent.NET、PHP的三级分类到各绑定包的安装方式、核心函数签名、错误处理与编译选项再到仓库统一的命名规范。读完本文你将掌握每个绑定的真实用法、它们背后的编译管线prql_to_pl→pl_to_rq→rq_to_sql以及如何在你的项目里快速接入 PRQL。一、绑定的三级生态一张图看懂维护边界PRQL 的编译器核心用 Rust 编写为了让其他语言的使用者也能编译 PRQL 查询官方维护了多个语言绑定。这些绑定并非一刀切而是按成熟度分为三档每档对应不同的维护承诺与 API 稳定性保证级别要求当前绑定Supported受支持有专门维护者实现了核心编译函数对这些函数有测试覆盖已发布到该语言的标准包仓库在 Taskfile.yaml 中有可引导开发环境的脚本代码风格检查工具linter / formatter已接入 pre-commit 或 MegaLinterJavaScript、Python、R、RustUnsupported不受支持功能可用但不满足上述全部标准编译器 API 变更不做门禁gate一旦失效会被降级为 NascentJava、Elixir、prqlc-cC 绑定Nascent萌芽期仍在开发中可能尚未完全可用.NET、PHP从 Bindings 索引文档 可以看到一个关键治理细节Supported 级别的绑定大多位于主 PRQL 仓库中任何对编译器 API 的改动都必须同步保证这些绑定兼容——We gate any changes to the compilers API on compatible changes to the bindings。这意味着只要你的语言绑定处于 Supported 级编译器升级时你的使用方式不会突然失效。而 Unsupported 级绑定则没有这道门禁属于能用但不保证的状态若损坏会被降级到 Nascent。二、核心编译管线所有绑定共享的同一套 API无论哪个语言绑定其背后调用的都是同一个 Rust 编译器prqlc。在 prqlc/prqlc/src/lib.rs 中可以找到绑定必须实现的五个核心函数也即 Supported 绑定要求的 core compile functions函数作用源码位置compile(prql, options)将 PRQL 查询直接编译为 SQL 字符串lib.rs#L189prql_to_pl(prql)将 PRQL 解析为 PL ASTPipeLine ASTlib.rs#L371pl_to_rq(pl)将 PL 解析、降级为 RQ ASTRelational Querylib.rs#L383rq_to_sql(rq, options)将 RQ AST 生成为最终 SQLlib.rs#L399pl_to_prql(pl)将 PL AST 重新格式化为 PRQL 文本用于格式化/美化lib.rs#L404因此各语言绑定暴露的 API 高度一致要么是一把梭的compile要么是分段式流水线prql_to_pl/pl_to_rq/rq_to_sql后者方便你介入中间环节做自定义处理比如检查中间 AST、注入优化。compile本质上是这三步的串联封装这是理解下面所有语言示例的共同前提。三、Supported 绑定详解3.1 JavaScript / TypeScriptprqlcnpm 包JavaScript 绑定源码位于 prqlc/bindings/js通过 WebAssembly 在 Node.js、浏览器和打包器环境中运行。安装与基础用法npm install prqlcNode.js 中的直接调用const prqlc require(prqlc); const sql prqlc.compile(from employees | select first_name); console.log(sql);多行查询同样支持const prqlc require(prqlc); const sql prqlc.compile( from employees select first_name ); console.log(sql);编译选项CompileOptions支持指定目标方言、是否格式化输出、是否附加签名注释const opts new prqlc.CompileOptions(); opts.target sql.mssql; opts.format false; opts.signature_comment false; const sql prqlc.compile(from employees | take 10, opts); console.log(sql);浏览器端ES Module 直接加载 WebAssemblyhtml head script typemodule import init, { compile } from ./dist/web/prqlc_js.js; await init(); const sql compile(from employees | select first_name); console.log(sql); /script /head body/body /html框架或打包器场景如 Vite、Webpackimport { compile } from prqlc/dist/bundler; const sql compile(from employees | select first_name); console.log(sql);暴露的完整函数签名来自 prqlc/bindings/js/README.mdfunction compile(prql_query: string, options?: CompileOptions): string; function prql_to_pl(prql_query: string): string; function pl_to_prql(pl_json: string): string; function pl_to_rq(pl_json: string): string; function rq_to_sql(rq_json: string): string;可见 JS 绑定完整镜像了第二节中的 Rust 核心管线。错误处理编译失败时抛出错误其message是一个 JSON 数组字符串包含结构化错误信息类型、错误码、原因、建议、源码位置等interface ErrorMessage { kind: Error | Warning | Lint; code: string | null; reason: string; hints: string[]; span: [number, number] | null; display: string | null; location: SourceLocation | null; } interface SourceLocation { start: [number, number]; // [行号, 列号]均从 0 开始 end: [number, number]; }捕获方式try { const sql prqlc.compile(from employees | foo first_name); } catch (error) { const errorMessages JSON.parse(error.message).inner; console.log(errorMessages[0].display); console.log(errorMessages[0].location); }本地开发npm run build会同时产出 Node、bundler、web 三种目标的dist产物npm test运行测试。若只想快速迭代可用PROFILEdev npm run build跳过 WASM 优化以缩短构建时间。实现上JS 绑定基于wasm-pack生成并在其上包了一层 npm 构建脚本以便用单个包同时分发node、bundler、web三个目标。3.2 PythonprqlcPyPI 包Python 绑定对应 crate 名为prqlc-python见 prqlc/bindings/prqlc-python发布到 PyPI 的包名同样是prqlc基于pyo3实现底层编译逻辑完全复用 Rust 编译器。安装与基础用法pip install prqlcimport prqlc prql_query from employees join salaries (emp_id) group {employees.dept_id, employees.gender} ( aggregate { avg_salary average salaries.salary } ) options prqlc.CompileOptions( formatTrue, signature_commentTrue, targetsql.postgres ) sql prqlc.compile(prql_query) sql_postgres prqlc.compile(prql_query, options)暴露的 API 全貌含默认值来自 prqlc/bindings/prqlc-python/README.mddef compile(prql_query: str, options: Optional[CompileOptions] None) - str: Compiles a PRQL query into SQL. ... def prql_to_pl(prql_query: str) - str: Converts a PRQL query to PL AST in JSON format. ... def pl_to_prql(pl_json: str) - str: Converts PL AST as a JSON string into a formatted PRQL string. ... def pl_to_rq(pl_json: str) - str: Resolves and lowers PL AST (JSON) into RQ AST (JSON). ... def rq_to_sql(rq_json: str, options: Optional[CompileOptions] None) - str: Converts RQ AST (JSON) into a SQL query. ... class CompileOptions: def __init__( self, *, format: bool True, target: str sql.any, signature_comment: bool True, ) - None: ... # format是否对生成的 SQL 进行美化排版默认 True # target目标方言默认 sql.any即由查询头部的 target 参数决定方言 # 可用 get_targets() 查看全部可选方言 # signature_comment是否在 SQL 末尾附加编译器签名注释默认 True def get_targets() - list[str]: List available target dialects for compilation. ...get_targets()与CompileOptions在 prqlc/bindings/prqlc-python/src/lib.rs 中有对应实现convert_options会将 Python 侧的CompileOptions转换为 Rust 编译器内部的prqlc_lib::Options再交给prqlc_lib::compile执行。这也印证了绑定只是薄壳真正干活的是 Rust 编译器这一架构事实。调试模块prqlc.debug额外提供列级血缘lineage分析能力属于实验性 API可能不稳定from prqlc import debug def prql_lineage(prql_query: str) - str: Computes a column-level lineage graph from a PRQL query. 返回 JSON 字符串详见 prqlc debug lineage CLI 命令。 ... def pl_to_lineage(pl_json: str) - str: Computes a column-level lineage graph from PL AST (JSON). ...开发流程项目使用uv管理依赖uv run pytest运行测试、uv run ty check做类型检查也可用task test。该包未被 pyprql、dbt-prql 等项目消费因而保持较活跃的迭代。3.3 RustprqlccrateRust 绑定就是编译器本身。文档指引读者直接查阅prqlccrate 的 API 文档rust.md仓库内的核心入口即 prqlc/prqlc/src/lib.rs。在 Rust 项目中通过 Cargo 引入[dependencies] prqlc … # 以 crates.io 上发布的最新版本为准然后即可调用prqlc::compile(prql, options)、prqlc::prql_to_pl(...)、prqlc::pl_to_rq(...)、prqlc::rq_to_sql(...)等函数compiler_version()位于 lib.rs#L142。Rust 绑定天然与编译器同步演进是其他所有绑定验证 API 兼容性的基准。3.4 RprqlrR 绑定的包名为prqlr见 r.md安装在 CRAN 上发布从文档可知由社区维护者 eitsupi 在独立的 PRQL/prqlc-r 仓库中维护。安装install.packages(prqlr)prqlr的一大特色是内置了knitrR Markdown 与 Quarto集成你可以在 R Markdown / Quarto 文档中直接嵌入 PRQL 转换结果让数据分析报告里的 SQL 生成过程可复现、可展示。四、Unsupported 绑定详解4.1 Javaprql-javaJava 绑定通过JNI调用 Rust 库源码见 prqlc/bindings/java在org.prql.prql4j.PrqlCompiler上暴露三个 native 方法public static native String toSql(String query, String target, boolean format, boolean signature) throws Exception; public static native String toJson(String query) throws Exception; public static native String format(String query) throws Exception;target方言名如sql.mysql完整列表见 Target and versionformat是否对 SQL 进行美化排版signature是否在末尾附加-- Generated by PRQL compiler version:...注释。该绑定仍处于早期阶段需要本地编译、尚未发布到 Maven。本地安装到本地 Maven 仓库./mvnw install -Dgpg.skiptrue注java/pom.xml将maven-gpg-plugin绑定在verify阶段而install会执行该阶段因此需要-Dgpg.skiptrue跳过签名。jar 不内置 native 库只有deployprofile 的cross.sh会填充src/main/resources所以消费者需要把工作区target/release下的libprql_java放到java.library.path上。依赖坐标version与 PRQL 发布版本独立维护dependency groupIdorg.prqllang/groupId artifactIdprql-java/artifactId version0.5.2/version /dependency使用示例import org.prql.prql4j.PrqlCompiler; class Main { public static void main(String[] args) throws Exception { String sql PrqlCompiler.toSql(from my_table, sql.mysql, true, true); System.out.println(sql); } }运行时必须把 native 库加入库路径否则静态初始化会失败并报libprql_java-linux64.so was not found inside JARjava -Djava.library.path/path/to/prql/target/release Main4.2 ElixirprqlElixir 绑定通过Rustler接入 Rust 编译器见 prqlc/bindings/elixir。安装依赖prql ~ 0.1.0def deps do [ {:prql, ~ 0.1.0} ] end基础用法交互式验证iex PRQL.compile(from customers, signature_comment: false) {:ok, SELECT\n *\nFROM\n customers\n} iex PRQL.compile(from customers\ntake 10, target: :mssql, signature_comment: false) {:ok, SELECT\n *\nFROM\n customers\nORDER BY\n (\n SELECT\n NULL\n ) OFFSET 0 ROWS\nFETCH FIRST\n 10 ROWS ONLY\n}从示例可见PRQL.compile/2返回{:ok, sql}元组且支持通过target: :mssql指定方言这里展示了 MSSQL 的OFFSET/FETCH分页写法。目前使用需要本地编译 Rust cratemix deps.get→mix compile→mix test。未来计划发布预编译产物让 Elixir 项目无需 Rust 工具链即可使用。4.3 C / C / Zigprqlc-cprqlc-c将 PRQL 编译为可供 FFI 调用的 C 库同时生成.a静态库与.so动态库任何支持 FFI 的语言例如 Golang都可以嵌入使用。完整 FFI 接口在 prqlc.h 中有内联文档C 头文件为 prqlc.hpp。链接方式以静态库为例来自 prqlc/bindings/prqlc-c/README.mdCGO_LDFLAGS-L/path/to/target/release -lprqlc_c -pthread -ldl -lm go buildmacOS 上还需追加-framework CoreFoundation。示例工程examples/minimal-c/main.c覆盖compile、自定义Options、错误处理以及分段式prql_to_pl/pl_to_rq入口examples/minimal-cpp使用生成的 C 头文件的等价流程examples/minimal-zigZig 通过cImport引入prqlc.h的示例。标准的链接参数可参考 examples/minimal-c/Makefile。头文件由cbindgen生成重新生成执行task build-prqlc-c-header即可。五、Nascent 绑定详解5.1 .NETprql-net.NET 绑定以net10.0库的形式提供见 prqlc/bindings/dotnet核心是静态类PrqlCompiler其Compile、PrqlToPl、PlToRq、RqToSql方法均返回携带Output字符串与Messages列表的Result。尚未发布到 NuGet。安装需要将libprqlc_c.soLinux、libprqlc_c.dylibmacOS或libprqlc_c.dllWindows与PrqlCompiler.dll一起放入项目bin目录例如{your_project}/bin/Debug/net10.0/。libprqlc_c库在运行时被动态导入。使用示例using Prql.Compiler; var options new PrqlCompilerOptions { Format false, SignatureComment false, }; var result PrqlCompiler.Compile(from employees, options); Console.WriteLine(result.Output);该绑定当前版本停在 0.1.0原因是等待prqlc-c更新到最新 API 后再对齐版本号。5.2 PHPprql-phpPHP 绑定通过FFI调用prqlc见 prqlc/bindings/php提供Compiler类包含compile、prqlToPL、plToRQ、rqToSQL四个方法。尚未发布到 Composer。安装需启用 PHP FFI 扩展在php.ini中设置ffi.enable true使用示例?php use Prql\Compiler\Compiler; $prql new Compiler(); $result $prql-compile(from employees); echo $result-output;开发环境可以使用 nix flake 建立包含 PHP、ext-ffi 与 Composer 的环境ext-ffi已在composer.json中声明mkdir -p ~/.config/nix echo experimental-features nix-command flakes ~/.config/nix/nix.conf nix shell github:loophp/nix-shell#env-php81 --impure构建与测试task build-php会依次执行 cargo 构建libprqlc_c、将libprqlc_c.*与prqlc.h复制进lib随后task test-php运行测试。代码风格用 PSR12 检查./vendor/bin/phpcs --standardPSR12 src tests。六、命名规范向prqlc-$lang收敛按 Bindings 索引文档 的说明PRQL 团队正逐步统一各绑定的命名约定Rust crate 统一命名为prqlc-$lang如prqlc-python、prqlc-c各语言包仓库中的发布名在可能的情况下统一为prqlc如 npm 的prqlc、PyPI 的prqlc。这也解释了为什么你在安装时会看到crate 名与包名不完全一致的现象Rust crate 用带语言后缀的名字区分而对外发布的包尽量用不带后缀的prqlc便于用户记忆和统一文档引用。七、如何选择与上手快速决策指南你的技术栈推荐绑定安装命令 / 方式成熟度Node.js / 浏览器 / 前端JavaScriptnpm install prqlcSupportedPython / 数据科学Pythonpip install prqlcSupportedRust 原生项目Rust在Cargo.toml引入prqlcSupportedR / R Markdown / QuartoRinstall.packages(prqlr)SupportedJava / JVMJava本地./mvnw install -Dgpg.skiptrueUnsupportedElixir / BEAMElixirmix deps.get后本地编译UnsupportedGo / Zig / 任意支持 FFI 的语言prqlc-c链接libprqlc_cUnsupported.NET / C#.NET拷贝libprqlc_c.*至 bin 目录NascentPHPPHP启用ffi.enable后加载Nascent核心建议追求稳定优先选择 Supported 级绑定因为它们有维护者、测试覆盖和 API 变更门禁需要中间 AST无论哪种语言都优先使用分段式prql_to_pl/pl_to_rq/rq_to_sql接口方便检查或改写中间表示指定方言编译前用get_targets()Python或查阅 target.md 确认可用方言名并通过CompileOptions/PrqlCompilerOptions的target参数传入错误排查编译报错时优先读取结构化错误字段kind、code、reason、hints、location其中的display字段是带标注的代码片段定位问题最快。所有绑定的底层能力都来自同一个 Rust 编译器prqlc/prqlc/src/lib.rs因此无论你使用哪种语言PRQL 查询的语法与编译行为都保持一致——学会一种绑定其他绑定即可举一反三。【免费下载链接】prqlPRQL is a modern language for transforming data — a simple, powerful, pipelined SQL replacement项目地址: https://gitcode.com/gh_mirrors/pr/prql创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表