首页/新闻资讯/正文详情

PRQL 的 Elixir 绑定:使用 Rustler NIF 在 Elixir 中编译 PRQL 查询

发布时间:2026/9/23 23:22:22 来源:云帆数科 栏目:资讯中心
PRQL 的 Elixir 绑定:使用 Rustler NIF 在 Elixir 中编译 PRQL 查询
后端【免费下载链接】prqlPRQL is a modern language for transforming data — a simple, powerful, pipelined SQL replacement项目地址https://gitcode.com/gh_mirrors/pr/prql点击查看免费下载本指南围绕 PRQL 仓库中的 Elixir 语言绑定位于 prqlc/bindings/elixir/README.md并被文档站点收录于 web/book/src/project/bindings/elixir.md展开介绍如何在 Elixir 项目中安装、调用PRQL.compile/2将 PRQL 管道式查询编译为 SQL并结合仓库源码剖析其 Rustler NIF 桥接层的实现原理、参数语义与开发测试流程。读完本文你将能够在自己的 Elixir 应用中直接驱动prqlc编译器并理解其编译管线的每一层PRQL → PL AST → RQ → SQL对应的 Elixir API。一、什么是 PRQL 的 Elixir 绑定PRQLPipelined Relational Query Language是一种面向数据转换的现代查询语言目标是成为 SQL 的管道式替代品。PRQL 编译器的核心是 Rust crateprqlc位于本仓库的 prqlc/prqlc 目录。为了让 Elixir 生态也能使用这一编译器仓库维护了一套独立的 Elixir 绑定工程其入口即 prqlc/bindings/elixir/README.md。该绑定基于Rustler实现Rustler 是 Elixir 社区中编写 Rust NIFNative Implemented Function原生函数的标准库它把prqlc的编译能力以原生函数的形式暴露给 Erlang VMElixir 侧则通过一个PRQL模块封装调用。从绑定分级来看Elixir 目前被归类为Unsupported非官方支持层级——功能可用但尚未达到需要维护者、完整测试覆盖、发布到官方包仓库等Supported标准详见 web/book/src/project/bindings/README.md 中的分级说明。二、安装与依赖2.1 在 mix 项目中引入依赖在mix.exs的deps/0中添加依赖def deps do [ {:prql, ~ 0.1.0} ] end随后执行mix deps.get拉取依赖。当前绑定工程的版本为0.1.0对 Elixir 的要求是~ 1.15见 prqlc/bindings/elixir/mix.exs 中project/0的声明。2.2 需要 Rust 工具链需要特别注意的是在写本文时该绑定尚未发布预编译产物。README 明确说明当前在 Elixir 项目中使用该绑定需要从本仓库源码编译 Rust crateprqlc/bindings/elixir/README.md的 Development 一节。也就是说开发/运行环境必须具备 Rust 工具链且mix compile时会触发对 NIF 的本地编译。绑定侧的依赖声明位于 prqlc/bindings/elixir/native/prql/Cargo.tomlprqlc以path ../../../../prqlc指向仓库内的编译器本体版本对应0.13.15并关闭默认特性default-features falserustler 0.38.0NIF 桥接库crate 类型为cdylib即编译为可供 Erlang VM 动态加载的共享库。Elixir 侧的构建依赖同样由 mix.exs 声明{:rustler, ~ 0.38.0}与仅开发期使用的{:ex_doc, ~ 0.21}。三、基本用法把 PRQL 编译为 SQL绑定对外暴露的入口是PRQL.compile/2。以下两个示例直接取自绑定 README也是PRQL模块的 doctest 用例见 prqlc/bindings/elixir/lib/prql.ex 中的doc与 prqlc/bindings/elixir/test/prql_test.exsiex 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}可以观察到两点返回值是{:ok, sql_string}元组成功时第二个元素就是可直接交给 SQL 驱动执行的 SQL 文本方言参数影响输出take 10在默认的:generic方言与:mssql方言下会生成不同的分页语法——MSSQL 使用OFFSET 0 ROWS ... FETCH FIRST 10 ROWS ONLY表达取前 10 行这正体现了 PRQL 面向多种 SQL 方言编译的能力。四、compile/2 的完整参数语义PRQL.compile(prql_query, opts \\ [])接受两个参数待编译的 PRQL 查询字符串以及关键字选项列表。其类型约束为when is_binary(prql_query) and is_list(opts)见 lib/prql.ex并通过struct(CompileOptions, opts)将选项结构化为 NIF 侧期望的 struct。4.1 target目标 SQL 方言target决定生成的 SQL 面向哪种数据库方言支持以下 12 个原子值原子值对应 prqlc 方言典型场景:genericGeneric默认通用 SQL:mssqlMsSqlMicrosoft SQL Server:mysqlMySqlMySQL:postgresPostgresPostgreSQL:ansiAnsiANSI 标准 SQL:bigqueryBigQueryGoogle BigQuery:clickhouseClickHouseClickHouse:duckdbDuckDbDuckDB:oracleOracleOracle:redshiftRedshiftAmazon Redshift:sqliteSQLiteSQLite:snowflakeSnowflakeSnowflake该参数默认值为:generic。有两个值得注意的语义未知原子回退到:genericRust 侧的target_from_atom见 native/prql/src/lib.rs会逐一分发各方言原子落入else分支时统一使用Generic方言始终优先于查询头doc中明确说明这里的方言总是胜过查询头中的target:sql.…参数且没有可以回退到查询头的值——即无法通过查询内声明覆盖compile/2传入的target。4.2 formatSQL 格式化开关format为布尔值控制是否将生成的 SQL 交给格式化器进行多行拆分与缩进美化默认值为true。README 与 doctest 中大量使用signature_comment: false正是为了让输出更简洁、便于断言。4.3 signature_comment签名注释开关signature_comment为布尔值控制是否在生成的 SQL 后附加编译器签名注释默认值为true。以上三个选项的默认值可以在 NIF 侧的 struct 定义中确认native/prql/src/lib.rsdefstruct target: :generic, format: true, signature_comment: true而在 Elixir 侧对应的类型声明位于 lib/prql/native.ex 的PRQL.Native.CompileOptions其t/0类型包含target: target(), format: boolean(), signature_comment: boolean()三个字段。Rust 侧将CompileOptions转换为prqlc::Options的实现impl FromCompileOptions for prqlc::Options进一步印证了选项的传递链路format、target、signature_comment直接映射到prqlc::Options对应字段同时固定设置display: prqlc::DisplayOptions::Plain即不做额外的展示层格式化。五、错误处理与 compile!/25.1 错误返回结构当查询无法编译时compile/2返回{:error, reason}其中reason是一个JSON 字符串。测试用例 prql_test.exs 给出了完整的错误 JSON 结构示例——对于查询invalid返回的错误 JSON 包含inner数组每个元素含kind、code、reason、hints、span、display带源码标注的可读错误信息与location起始/结束行列坐标等字段。这得益于 Rust 侧to_result_tuple的实现prqlc::ErrorMessages会被序列化为 JSONe.to_json()作为{:error, json}元组的第二个元素返回。在应用侧你可以用任意 JSON 解码库如Jason解析该错误字符串从中提取span如1:0-7与display字段做进一步展示或定位。5.2 断言式 APIcompile!/2如果希望出错时直接抛出异常而非返回元组可以使用compile!/2spec compile!(binary(), [compile_opts()]) :: binary() def compile!(prql_query, opts \\ []) do case compile(prql_query, opts) do {:ok, result} - result {:error, reason} - raise PRQL.PRQLError, reason end endcompile!/2成功时直接返回 SQL 字符串失败时抛出PRQL.PRQLError异常。异常模块定义在 lib/prql/errors.ex它基于defexception [:message, :error]exception/1回调将message固定为Error compiling PRQL query原始错误 JSON 存放在:error字段中。六、编译器管线的逐层 API除了端到端的compile/2绑定还暴露了 PRQL 编译器内部三条管线的逐步调用函数对应prqlc库的核心编译流程Elixir 函数阶段输入输出prql_to_pl/1PRQL → PL ASTJSONPRQL 查询字符串{:ok, pl_json}或{:error, json}pl_to_rq/1PL ASTJSON → RQJSONPL 的 JSON 表示{:ok, rq_json}或{:error, json}rq_to_sql/1RQJSON → SQLRQ 的 JSON 表示{:ok, sql}或{:error, json}每个函数都有对应的!版本prql_to_pl!/1、pl_to_rq!/1、rq_to_sql!/1语义与compile!/2一致成功返回字符串失败抛出PRQL.PRQLError。Rust 侧实现native/prql/src/lib.rs揭示了这些函数与prqlc库的对应关系prql_to_plprqlc::prql_to_pl解析出 PL AST 后再经prqlc::json::from_pl序列化为 JSONpl_to_rq先prqlc::json::to_pl反序列化 PL JSON经prqlc::pl_to_rq生成 RQ再由prqlc::json::from_rq输出 JSONrq_to_sql先prqlc::json::to_rq反序列化 RQ JSON再调用prqlc::rq_to_sql生成 SQL——代码注释也指出此处目前只使用默认 Options。这套分层 API 对需要自定义编译管线例如在 PL/RQ 层做分析或转换的 Elixir 开发者非常有用可以嵌入自己的中间处理步骤。七、架构原理Elixir 如何调用 Rust 编译器绑定采用标准的 Rustler NIF 架构整体数据流如下Elixir 调用层lib/prql.ex 的PRQL模块将用户参数结构化为PRQL.Native.CompileOptions调用PRQL.Native.compile/2等 NIF 函数NIF 占位层lib/prql/native.ex 使用use Rustler, otp_app: :prql声明 NIF 宿主模块。未加载 NIF 时各函数返回:erlang.nif_error(:nif_not_loaded)保证模块在无原生库环境下仍可加载Rust 实现层native/prql/src/lib.rs 通过#[rustler::nif]标注四个导出函数并以rustler::init!(Elixir.PRQL.Native)注册到名为Elixir.PRQL.Native的模块返回值编码Rust 侧把ResultString, prqlc::ErrorMessages统一转换为Response一个NifTuple包含:ok/:error原子与结果字符串映射为 Elixir 的{:ok, binary()} | {:error, binary()}元组。值得注意的实现细节Rust 侧CompileOptions通过#[derive(NifStruct)]与#[module PRQL.Native.CompileOptions]声明与 Elixir struct 的映射关系因此 Elixir 侧struct(CompileOptions, opts)生成的 struct 可以直接作为 NIF 参数传递。另外该 crate 在wasm目标下被显式排除#![cfg(not(target_family wasm))]表明它面向原生环境运行。八、开发与测试流程README 的 Development 一节给出了本地开发的三个标准步骤mix deps.get # 安装 Elixir 依赖 mix compile # 编译工程含 Rust NIF mix test # 运行测试测试工程包含 test/prql_test.exs 与 test/test_helper.exs。其中测试覆盖了两类核心场景成功路径PRQL.compile(from customers, signature_comment: false)断言其输出与预期 SQL 完全一致错误路径PRQL.compile(invalid, ...)断言返回的{:error, json}经Jason.decode后与预期的错误结构逐字段相等。此外prql_test.exs中的doctest PRQL会直接执行PRQL模块doc中的 doctest 示例确保文档中的用法示例持续可验证。NIF 的构建说明见 native/prql/README.mdNIF 会随项目一起编译并自动加载进PRQL.Native模块。九、当前状态与未来规划绑定 README 明确标注我们正处于 Elixir 绑定的早期开发阶段We are in the early stages of developing Elixir bindings。从 web/book/src/project/bindings/README.md 的分级看Elixir 绑定当前属于Unsupported层级功能可正常工作但尚未满足 Supported 所需的条件有维护者、覆盖核心编译函数及对应测试、发布到语言官方包仓库、在Taskfile.yaml提供开发环境引导脚本等。README 提及的未来工作包括发布预编译产物届时 Elixir 项目将无需本地 Rust 工具链即可直接使用 PRQL 编译能力。在此之前任何使用该绑定的 Elixir 项目都依赖 Rust 工具链与仓库内prqlccrate 的本地编译。十、小结本文围绕 PRQL 的 Elixir 绑定完整覆盖了从依赖安装、PRQL.compile/2基本用法、三大编译选项target/format/signature_comment语义、错误处理与compile!/2、编译器逐层 API到 Rustler NIF 桥接层源码剖析与开发测试流程的全部内容。你可以基于 prqlc/bindings/elixir/lib/prql.ex 的公开 API 直接集成也可以参考 native/prql/src/lib.rs 理解底层调用链从而在 Elixir 项目中获得完整的 PRQL 编译能力。赞分享后端【免费下载链接】prqlPRQL is a modern language for transforming data — a simple, powerful, pipelined SQL replacement项目地址https://gitcode.com/gh_mirrors/pr/prql点击查看免费下载相关推荐PRQL Elixir Bindings在 Elixir 中编译 PRQL 查询为 SQL 的完整指南PRQL Elixir Bindings在 Elixir 中编译 PRQL 查询为 SQL 的完整指南 PRQLPipelined Relational Q后端使用 prql-php通过 PHP FFI 调用 PRQL 编译器将 PRQL 查询编译为 SQL使用 prql php通过 PHP FFI 调用 PRQL 编译器将 PRQL 查询编译为 SQL PRQLPipelined Relational Que后端PRQL PHP 绑定指南使用 prql-php 通过 FFI 将 PRQL 编译为 SQLPRQL PHP 绑定指南使用 prql php 通过 FFI 将 PRQL 编译为 SQL prql php 是 PRQL 编译器在 PHP 生态中的官方绑后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

Regal 规则忽略完全指南:掌握 Rego 静态检查的优先级体系与配置方法
Regal 规则忽略完全指南:掌握 Rego 静态检查的优先级体系与配置方法

后端认证鉴权云原生 【免费下载链接】opa Open Policy Agent (OPA) is an open source, general-purpose policy engine. 项目地址: https://gitcode.com/gh_mirrors/op/opa 点击查看 免费下载 Regal 是 Open Policy Agent (OPA) 生态中面向 Rego 策略代码的 linte… · 2026/9/23 23:22:16

LanceDB JS SDK 的 QueryExecutionOptions:批大小与查询超时控制实战指南
LanceDB JS SDK 的 QueryExecutionOptions:批大小与查询超时控制实战指南

向量数据库数据库人工智能后端 【免费下载链接】lancedb Developer-friendly OSS embedded retrieval library for multimodal AI. Search More; Manage Less. 项目地址: https://gitcode.com/gh_mirrors/la/lancedb 点击查看 免费下载 本文围绕 LanceDB 官方 Node… · 2026/9/23 23:22:09

BERT微调多标签文本分类:数据、训练与避坑全攻略
BERT微调多标签文本分类:数据、训练与避坑全攻略

简介:面向自然语言处理入门与实战开发者,这份下载包提供了基于Keras和Keras-bert的文本多标签分类完整实现。项目选用2020语言与智能技术竞赛事件抽取任务作为样例数据,展示BERT微调在真实场景下的落地方案,适合快速入门或改造复用… · 2026/9/23 23:22:09

中文NLP实战:用SVD与SGNS构建子词向量解决OOV问题
中文NLP实战:用SVD与SGNS构建子词向量解决OOV问题

简介:面向自然语言处理学习者,尤其适合需要完成子词向量课程作业的学生。项目围绕汉语子词向量构建与评测,分别实现基于SVD分解和基于SGNS的两种方法。SVD方法先以K5窗口获取高维distributional表示,再进行降维;SGNS方… · 2026/9/23 23:58:34

Python毕业设计评价系统:Flask+SQLite教学质量管理实战
Python毕业设计评价系统:Flask+SQLite教学质量管理实战

简介:本资源是一套基于Python开发的毕业设计教学质量评价系统完整源码与数据库实现,面向高校教务管理人员、计算机专业毕业设计指导教师及本科毕设项目开发者,旨在解决毕业设计过程中的多角色协同评价、成绩量化分析与教学质量管理难题。压缩… · 2026/9/23 23:58:34

水下生物目标检测实战:YOLO工程与PyTorch训练推理全流程解析
水下生物目标检测实战:YOLO工程与PyTorch训练推理全流程解析

简介:面向水下生物目标检测场景,这份基于Python与PyTorch的深度学习资源包,整合了YOLO模型训练与推理所需的数据集、脚本及预训练权重,适合有一定深度学习基础、希望快速上手目标检测项目的开发者。资源共1830个文件,压… · 2026/9/23 23:58:28

深度Q学习网络(DQN)股票交易实战:从环境建模到回测避坑全解析
深度Q学习网络(DQN)股票交易实战:从环境建模到回测避坑全解析

简介:一份基于深度Q学习网络的股票交易策略设计源码,面向量化交易入门者、金融AI研究者和Python算法开发人员,解决如何利用强化学习对历史行情建模并自动生成交易决策的问题。压缩包共24个文件,约12.21MB,包含Python核… · 2026/9/23 23:58:28

医学图像分类实战:肾脏数据集组织、yolov5训练与混淆矩阵评估
医学图像分类实战:肾脏数据集组织、yolov5训练与混淆矩阵评估

简介:一套针对肾脏结节与肿瘤识别的医学图像分类数据集,包含正常、结节、肿瘤三种标签,专为基于深度学习的影像分类场景设计,适用于医学影像入门实验、算法验证及竞赛练习。数据已按照训练集、验证集、测试集划分并保存在data目录… · 2026/9/23 23:58:22

Android音乐播放器开发:从零实现本地播放与后台保活
Android音乐播放器开发:从零实现本地播放与后台保活

简介:这是一份面向Android开发初学者与进阶学习者的完整音乐播放器App实战项目资源,聚焦移动端多媒体应用开发核心能力训练,涵盖用户认证、本地音乐管理、UI交互与后台播放服务等典型场景。资源包共57个文件,包含14个Java源码文件… · 2026/9/23 23:58:15

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码