
Baserow 公式字段完全指南从concat入门到 SQL 编译原理【免费下载链接】baserowBuild databases, automations, apps agents with AI — no code. Open source platform available on cloud and self-hosted. GDPR, HIPAA, SOC 2 compliant. Best Airtable alternative.项目地址: https://gitcode.com/GitHub_Trending/ba/baserowBaserow 的公式字段Formula Field允许你为字段中的每一行单元格基于一段公式动态计算结果语法与主流电子表格工具类似且拥有不断扩充的函数库。本指南以 Understanding Baserow Formulas 为核心逐步讲解如何编写、调试 Baserow 公式并深入源码剖析公式从文本到 PostgreSQL 查询的完整编译链路。读完本文你将掌握公式字段的日常用法文本拼接、数值运算、条件判断、日期计算、常见错误排查以及函数注册、类型推导、运算符重载等底层机制。什么是 Baserow 公式字段一个 Baserow 公式字段让你创建内容由你提供的 Baserow 公式计算而来的字段。Baserow 公式本质上是一段按照特定规则书写的文本Baserow 能够解析并执行它。例如文本11就是一个合法的 Baserow 公式它会在每一行计算出结果2。与普通字段不同公式字段只有一个公式整个字段的所有单元格都由该公式按行计算得出——这决定了公式字段的单元格无法被手动编辑详见文末 FAQ。一个简单的公式示例假设你有一张表其中包含一个名为text field的普通文本字段共有 3 行分别存放文本one、two和three。此时如果你新建一个公式字段并写入公式concat(Number, field(text field))得到的表格将是text fieldformula fieldoneNumber onetwoNumber twothreeNumber three可以看到公式字段的每一个单元格都是基于同一行text field的单元格值计算出来的。公式字段可以引用同表其他字段甚至其他公式字段但不能引用自身循环引用同样被禁止见 formula-technical-guide.md 的 Field References 章节。逐段拆解一个简单公式我们把concat(Number, field(text field))拆开来看理解每一部分的含义concat这是 Baserow 众多公式函数之一作用是把所有输入拼接成一段文本。(左括号表示接下来要开始向函数传入输入参数。Number传入concat的第一个输入是一个字面量文本Number。在公式中书写文本字面量时必须用引号包裹Baserow 同时支持单引号与双引号见 BaserowFormula.g4 中的SINGLEQ_STRING_LITERAL/DOUBLEQ_STRING_LITERAL词法规则。,逗号用于分隔函数的多个输入参数。field(text field)传给concat的第二个输入。field()是对同表字段的引用参数为该字段名。公式字段每个单元格计算时这个引用都会被替换为对应行在text field字段中的实际值。理论上你可以继续用逗号追加任意多个输入。)右括号表示函数输入结束与左括号一一匹配。什么是公式函数公式中的函数按各自类型接收一定数量的输入对输入做计算后产出一个输出。有些函数只接受特定类型的输入例如datetime_format只接受两个参数第一个必须是日期可以是日期字段的引用也可以是能算出日期的子公式第二个必须是文本。从语法层面看函数调用在 BaserowFormula.g4 中被定义为func_name OPEN_PAREN (expr (COMMA expr)*)? CLOSE_PAREN即函数名 括号 逗号分隔的表达式列表。所有可用函数都会在编辑公式字段时展开的编辑框中列出供你随时查阅。在公式中使用数字公式天然支持数值计算标准数学运算符、-、*、/都可用。你可以在公式中直接书写整数或小数例如(field(number field) 10.005) / 10优先级遵循 BaserowFormula.g4 中规则的书写顺序*、/的规则位于、-之前因此11/2会先计算1/2这与常规数学优先级一致括号OPEN_PAREN expr CLOSE_PAREN则用于显式控制结合顺序。Invalid Number 错误如果在公式单元格中看到Invalid Number说明该行的公式执行了以下非法操作之一将数字除以 0使用tonumber函数把文本转换为数字时失败因为该文本不是合法数字计算出的数字超过了允许的最大值10^50。值得一提的细节是公式结果最终被存入 PostgreSQL 列数字类型默认与NUMBER_MAX_DECIMAL_PLACES等精度约束相关参见 fields/models.py因此超大数值会触发上限校验。条件计算需要按条件计算结果时可使用if函数配合比较运算符。例如下面的公式判断某个日期字段是否为一个月的第一天IF(day(field(some date)) 1, true, false)可用的比较运算符包括、、、、和!。此外从语法定义还可以看到AND与||OR逻辑运算符它们与比较运算符一样在底层被映射为对应的函数调用详见下文运算符即函数。使用日期使用todate函数可以在公式内创建一个常量日期例如todate(2020-01-01 10:20:30, YYYY-MM-DD HH:MI:SS)第一个参数是文本形式的日期第二个参数是该日期文本的格式。日期处理相关的辅助工具可在 core/formula/utils/date.py 中看到实现。使用日期间隔两个日期相减会返回它们之间的时间差field(date a) - field(date b)date_interval函数则用于在公式内部创建日期/时间间隔。需要基于一个间隔计算新的日期时可以这样写field(my date column) - date_interval(1 year)这条公式的含义是用my date column的日期减去 1 年得到一个新的日期。日期与间隔的加减、求差等运算由公式类型系统在类型检查阶段完成类型匹配再翻译为底层表达式。FAQ为什么我不能修改公式字段单元格的值公式字段的单元格值无法直接修改因为整个字段共享同一条公式所有单元格的值都由它统一计算。如果你已完成计算、想对个别结果做针对性编辑建议把公式字段转换回普通字段再修改。删除公式引用的字段会发生什么如果一个字段被公式引用而你删除了被引用的字段公式字段会变成无效状态并显示错误。修复方式有四种恢复被删除的字段、新建一个同名的新字段、修改公式使其不再引用被删除的字段、或重命名其他字段使其与引用名匹配。这一行为背后有完整的机制支撑删除字段时系统会把引用它的公式标记为 broken 并报错当用户创建一个同名新字段或恢复、重命名字段时那些 broken 公式会重新变为有效。因此创建、恢复或重命名字段都可能改变同表其他公式字段的类型系统会相应地重新检查并重新推导整张表的公式类型详见 formula-technical-guide.md 的 Field Renaming 章节。进阶公式的底层实现原理作为开源项目Baserow 公式的实现是一条完整的技术链路从语法解析一路走到 SQL 求值。理解它能帮助你更好地掌握公式行为也为插件扩展提供指引。相关模块位于 backend/src/baserow/contrib/database/formula/ 下。语法定义与解析器生成Baserow 公式语言是开源的自研表达式语言拥有完整的语法/文法定义语法定义文件见 formula/BaserowFormula.g4 与 formula/BaserowFormulaLexer.g4采用 ANTLR4 文法后端用于校验公式合法性并构造 Python AST 的解析器位于 backend/src/baserow/core/formula/parser/其中generated/目录存放 ANTLR 生成的代码如BaserowFormula.py、BaserowFormulaLexer.py前端浏览器中用于校验公式合法性的解析器同样由该文法生成。语法文件中还保留了向后兼容的FIELDBYID按 ID 引用字段语法但已标记为 deprecated 不再推荐使用目前推荐统一使用field(字段名)按名称引用。Python AST 与类型系统后端内部使用一套 Python 抽象语法树AST表示公式定义在 ast/tree.py包括字符串/整数/小数/布尔字面量、字段引用、函数调用等节点类型推导算法位于 types/其中 types/formula_type.py 定义BaserowFormulaType、BaserowFormulaValidType与BaserowFormulaInvalidTypetypes/formula_types.py 则实现了BaserowFormulaTextType、BaserowFormulaNumberType、BaserowFormulaDateType、BaserowFormulaBooleanType等具体类型。类型系统决定了每个公式字段的公式类型并由此影响排序、过滤等行为。公式最终如何计算编译为 Django 表达式与 SQL公式最终会被编译成一条预编译的 SQL 语句用于在 PostgreSQL 列中计算并存储公式结果。实现路径是先把 Baserow 公式转换为 Django Expression核心文件 generator.py 与 django_expressions.py。这也解释了为什么公式计算快所有行的求值都在数据库侧以 SQL 批处理完成而非在应用层逐行循环。函数注册表与插件扩展每个公式函数都通过实现BaserowFunctionDefinition并注册到formula_function_registry中来定义。注册表本身在 registries.py 中定义class BaserowFormulaFunctionRegistry(Registry): name formula_function does_not_exist_exception_class FormulaFunctionTypeDoesNotExist formula_function_registry BaserowFormulaFunctionRegistry()插件可以非常容易地新增自定义公式函数实现一个BaserowFunctionDefinition并注册进formula_function_registry即可。函数具有特定或不限数量的参数参数可被类型检查并强制为特定类型否则报错函数本身拥有返回值类型。丰富的内置函数实现如concat、if、day、todate、date_interval、tonumber等集中在 ast/function_defs.py每个函数都定义了如何将自身转换为 Django Expression 来计算结果。运算符即函数支持重载运算符本质上被实现为运算符到BaserowFunctionDefinition的映射例如运算符只是调用BaserowAdd函数的一种花哨写法运算符的优先级则由 BaserowFormula.g4 中规则排列顺序决定越靠前的规则优先级越高。同时运算符支持重载根据输入类型采用不同实现。例如a b会拼接两个字符串而1 2执行数值加法。从 formula_types.py 可以看到文本类型定义了addable_types可相加类型与add方法其中文本的被实现为转发到concat函数调用。类型强制转换与类型格式化选项类型系统通常会把类型强制转换为普通用户直觉上合理的方式。例如CONCAT(field(a date field), field(a boolean field))无需显式把每个参数 cast 成文本即可正常工作。但系统不会允许奇怪的操作比如拿布尔值去和日期比较此时会直接给出类型错误而不是默默返回false。公式类型还允许用户覆盖格式化选项。举例来说公式字段11初始被推导为BaserowFormulaNumberType(num_decimal_places0)该推导类型被持久化到FormulaField模型上formula_typenumber、num_decimal_places0其他类型选项字段为 null此时所有单元格显示为1用户可以自行编辑这些持久化的类型选项来改变类型与显示方式例如把num_decimal_places改为2对应模型字段同步更新类型变为BaserowFormulaNumberType(num_decimal_places2)此后单元格显示为1.00。这些用户提供的格式化选项在公式整体类型发生变化时会重置否则会一直保留。无效公式类型与字段重命名对于(1a)这类类型不合法的公式系统存在一个 invalid 类型它会把错误信息存储在FormulaField模型上。由于公式字段可能引用其他字段每当字段被编辑、删除、恢复或创建时都可能影响依赖它的其他公式字段。此时系统会构造整张表所有字段的引用树重新计算每个字段的类型若类型发生变化则刷新对应公式字段的值——相关迁移与重算逻辑见 formula/migrations/。重命名字段时公式中对它的引用会被一并更新为新的字段名并把更新后的字段返回给浏览器删除字段时引用它的公式被标记为 broken 并报错之后用户新建同名新字段即可让这些公式自动恢复有效。排序与过滤公式字段公式字段可以基于自身的BaserowFormulaType参与 Baserow 现有的视图过滤与排序。定义视图过滤器时通过FormulaFieldType.compatible_with_formula_types辅助函数声明哪些 Formula Type 与该过滤器兼容即可让公式字段支持相应过滤条件。测试与验证后端为公式系统配备了较为完整的测试可在 backend/tests/baserow/contrib/database/formula/ 与 backend/tests/baserow/core/formula/ 下查看例如test_baserow_formula_results.py公式计算结果、test_rename_field_references.py字段重命名对公式引用的影响等这些测试是理解公式行为边界的最佳参考。当前不支持的字段类型与未来功能截至当前版本以下字段类型还无法在公式中被引用和使用Collaborators协作者Created by创建者Last modified by最后修改者Password密码AI Prompt同时更多公式函数正在持续开发中。如果你有特别需要的函数可以在官方社区论坛提出帮助团队确定新函数的优先级。小结从用户视角看Baserow 公式字段是一条写一段文本 → 全表按行求值的高效计算方案用field(字段名)引用同表字段用concat、if、todate、date_interval等函数与 - * /、比较、逻辑运算符组合出任意复杂度的计算并可通过类型格式化选项控制显示效果。从实现视角看公式语言经历了 ANTLR 文法解析 → Python AST → 类型推导 → Django Expression → PostgreSQL SQL 的完整编译管线函数注册表机制让插件可以低成本扩展新函数。建议进一步阅读 Baserow Formula 技术指南 获取面向开发者的完整实现细节。【免费下载链接】baserowBuild databases, automations, apps agents with AI — no code. Open source platform available on cloud and self-hosted. GDPR, HIPAA, SOC 2 compliant. Best Airtable alternative.项目地址: https://gitcode.com/GitHub_Trending/ba/baserow创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考