Baserow 特性开关(Feature Flags)机制:开启、关闭与自研一个新开关的完整指南

发布时间:2026/9/17 22:52:50
Baserow 特性开关(Feature Flags)机制:开启、关闭与自研一个新开关的完整指南 Baserow 特性开关Feature Flags机制开启、关闭与自研一个新开关的完整指南【免费下载链接】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 使用基础的特性开关feature flags机制允许尚未完成的功能先被合并进代码库甚至在正式发布中随版本分发而不影响默认用户体验。本文以 Baserow 官方开发文档 feature-flags.md 为核心结合后端与前端的实际实现源码系统讲解当前可用的开关清单、环境变量的开启方式含通配符、命名规范以及如何在后端Python和 Web 前端JS中创建并使用一个新的特性开关并完整保留ai-providers这一关键开关的存量升级、回滚策略。一、特性开关的定位与设计哲学Baserow 的 feature flag 是一个“最小化”的门禁机制不引入复杂的配置中心或第三方服务仅通过一个环境变量FEATURE_FLAGS即可控制整个栈Django 后端 Nuxt 前端中未定型功能的可见性与可用性。其设计目标是让未完成、不稳定或正在实验的功能可以先行合并进主干allow unfinished features to be merged and/or released而不阻塞其他功能的开发节奏默认对最终用户完全透明——不设置该环境变量时所有受控功能均处于关闭状态前后端共享同一份环境变量值保证“后端 API 已开放、前端入口却未显示”之类的状态错位不会出现。从源码结构看整个机制在两端各只有一个核心文件承载后端为 feature_flags.py前端为 featureFlags.js加上配置解析入口 base.py 中的环境变量读取即构成完整的特性开关体系。二、当前可用的特性开关清单Baserow 文档要求开发者将新增/移除的开关同步维护到官方文档的清单中。当前仓库中定义的开关共有两个见 feature_flags.py开关名称环境变量值作用定义位置后端 / 前端ai-providersai-providers实例管理区与工作区设置中的 AI 供应商AI Provider管理能力即把 AI 供应商凭据从“环境变量/遗留 JSON”迁移到数据库管理的完整流程FF_AI_PROVIDERSfeature_flags.py / featureFlags.jsbutton-fieldbutton-field启用 Button 字段类型关联社区 issue #1722FF_BUTTON_FIELDfeature_flags.py / featureFlags.js其中ai-providers是两者中复杂度最高的开关它背后涉及一次跨“双状态”开关开/关两种状态都要能正确运行的数据迁移、管理命令式的数据导入以及一套完整的升级与回滚预案。下文单独展开。ai-providers开关的升级与回滚实战预案这一部分是原文档中最具实战价值的运维指引适用于已在生产环境运行、需要打开ai-providers开关的存量安装必须逐步执行1. 数据库迁移的双状态兼容迁移core.0120会在开关开启与关闭两种状态下都会执行它为既有模型增加 “AI Agent eligibility”AI Agent 使用资格保留模型的其他特性不变并对未显式选择的特性默认授予 “AI Fields AI Agent”。因此保持开关关闭状态时无需导入任何供应商也无需重新发布republish任何站点或工作流。2. 五步升级流程第 1 步暂停所有 AI 设置变更保持开关处于关闭状态部署并排干drain旧版 web 与 worker 进程。如果此前曾使用FEATURE_FLAGS*应先改为显式列出其他开关名的白名单并排干使用通配符的进程也可以直接先停掉旧进程。第 2 步预览两次导入——环境变量形式的设置将转为“实例级供应商”遗留的工作区 JSON 将转为“工作区级供应商”。检查告警并协调冲突just b manage migrate_ai_provider_settings --scope instance just b manage migrate_ai_provider_settings --scope workspace第 3 步先应用实例级设置再应用工作区级设置注意追加--apply真正写入just b manage migrate_ai_provider_settings --scope instance --apply just b manage migrate_ai_provider_settings --scope workspace --apply每个 scope 的导入是原子的且只导入缺失的供应商、不会打印凭据重复执行导入不会把变更同步回已存在的供应商。第 4 步带着已启用ai-providers的环境变量重启所有 web、backend、worker 进程并排干旧进程。恢复设置变更之前重新加载管理员/编辑者的浏览器标签页如果要新增 Google、Groq 等供应商类型则需重新加载所有浏览器标签页。第 5 步重新发布那些包含“遗留 AI 设置快照”的站点与 workflow使其采纳实时的数据库凭据与资格信息。注意republish 会同时把待处理的草稿改动变为线上状态需先审查显式的完整集成覆盖explicit complete integration overrides则保持独立不受影响。3. 已在用该开关的安装 回滚策略对于已启用该开关的安装暂停设置变更在停掉旧进程的前提下升级恢复前重新加载管理员/编辑者标签页除非已确认没有可用遗留设置否则保持开关开启回滚时保留数据库 schema并在关闭开关前先核实遗留设置仍然完好。数据库中的变更不会被反向拷贝回遗留格式删除一个已导入的工作区供应商会同时删除其对应的遗留 JSON回滚后同样要检查已发布的站点与 workflow。Kuma 遗留模型与 provider-native 凭据不参与导入文档同时指向 Kuma 模型设置的过渡测试计划仓库中为 kuma-model-settings-test-plan.md用于演练采纳adoption与回滚全过程。三、开启特性开关环境变量与 just 命令精确开启指定开关设置环境变量FEATURE_FLAGSfeature1,feature2,feature3逗号分隔、可空格即可开启对应开关。使用just时FEATURE_FLAGSfeature1,feature2,feature3 just dc-dev up -d也可以把该变量持久化到对应开发环境的配置文件中.env.docker-devDocker 开发环境.env.local本地开发环境。开启全部开关通配符使用*作为开关值可一次性启用所有特性开关无需逐一列出FEATURE_FLAGS* just dc-dev up -d需要注意*的运维含义ai-providers升级流程中专门提示若环境曾使用FEATURE_FLAGS*升级时应先改回“显式开关白名单”并排干仍带着通配符运行的进程避免新旧进程读取到不一致的开关集合。源码实现环境变量如何被解析后端在 Django 配置层解析该变量base.py# A comma separated list of feature flags used to enable in-progress or not ready # features for developers. See docs/development/feature-flags.md for more info. FEATURE_FLAGS [ flag.strip().lower() for flag in os.getenv(FEATURE_FLAGS, ).split(,) ]即按逗号切分 → 逐项strip()去空白 → 统一lower()转小写 → 存为列表。这解释了命名规范中“首尾空格会被自动修剪”这一条见下文也意味着开关匹配是大小写不敏感的。四、命名规范Naming ConventionBaserow 要求新特性开关满足以下约定字母数字加短横线alphanumeric with dashes如ai-providers、button-field不能以空格开头或结尾——环境变量中的开关值会在使用时被自动修剪trim这一点由后端解析代码flag.strip().lower()base.py直接实现对易用性友好每个特性唯一unique per feature一个开关只对应一个功能避免复用导致开关语义混乱。五、创建一个特性开关后端Python / Django官方文档给出的模板是在baserow.core.feature_flag模块中以FF_FEATURE_NAME feature_name形式声明常量然后在使用处导入判断。需要说明的是当前仓库中该模块的实际文件名是复数形式feature_flags.pyfeature_flags.py引用时应以此为准# 在 baserow.core.feature_flags 中按 FF_FEATURE_NAME feature_name 格式添加常量 # 例如 FF_FEATURE1 feature1 # 在功能代码文件中导入所需常量与判断函数 from baserow.core.feature_flags import FF_FEATURE1, feature_flag_is_enabled # 判断特性是否启用 if feature_flag_is_enabled(FF_FEATURE1): # do the feature # 或者未启用时直接抛异常 feature_flag_is_enabled(FF_FEATURE1, raise_if_disabledTrue)实际实现feature_flags.pyFF_ENABLE_ALL * FF_AI_PROVIDERS ai-providers FF_BUTTON_FIELD button-field def feature_flag_is_enabled(feature_flag: str, raise_if_disabledFalse) - bool: Check if a specific feature flag is enabled. if FF_ENABLE_ALL in settings.FEATURE_FLAGS: return True is_enabled feature_flag.lower() in settings.FEATURE_FLAGS if not is_enabled and raise_if_disabled: raise FeatureDisabledException( fThe feature flag {feature_flag} is not enabled. ) return is_enabled实现上有三个值得注意的细节通配符短路只要解析后的列表中含有*任何开关直接返回True不再做名称匹配再次小写化feature_flag.lower()与已小写的settings.FEATURE_FLAGS比较双保险保证大小写无关raise_if_disabled语义功能接口可在被调用时直接抛出FeatureDisabledException定义于 exceptions.py而不是静默降级便于调用方明确感知“功能被开关挡住”这一状态测试环境默认全开test.py 中设置FEATURE_FLAGS *即单元测试始终运行在所有开关打开的状态下保证未发布功能同样被测试覆盖。Web 前端JS / Nuxt在core/plugins/featureFlags.js中以同样的常量格式导出当前仓库实际路径为 web-frontend/modules/core/plugins/featureFlags.js// 在 core/plugins/featureFlags.js 中添加 FF_FEATURE_NAME feature_name // 例如 export const FF_FEATURE1 feature1; // 在组件中通过注入的 $featureFlagIsEnabled 判断 methods: { someComponentMethod() { if (this.$featureFlagIsEnabled(FF_FEATURE1)) { // do the feature } } }前端插件的完整实现featureFlags.jsimport { useRuntimeConfig } from #imports const FF_ENABLE_ALL * export const FF_BUTTON_FIELD button-field export const FF_AI_PROVIDERS ai-providers function getFeatureFlags(env) { return (env.FEATURE_FLAGS || ) .split(,) .map((flag) flag.trim().toLowerCase()) } function featureFlagIsEnabled(featureFlags, flag) { if (featureFlags.includes(FF_ENABLE_ALL)) { return true } else { return featureFlags.includes(flag.toLowerCase()) } } export default defineNuxtPlugin(() { const runtimeConfig useRuntimeConfig() const featureFlagsValue runtimeConfig.public.featureFlags const FEATURE_FLAGS getFeatureFlags({ ...runtimeConfig.public, FEATURE_FLAGS: featureFlagsValue, }) return { provide: { featureFlagIsEnabled: (flag) featureFlagIsEnabled(FEATURE_FLAGS, flag), }, } })可以看到前端与后端在语义上完全对齐同样是逗号切分 trimtoLowerCasegetFeatureFlags同样支持*通配短路判断函数featureFlagIsEnabled与后端的feature_flag_is_enabled行为一一对应。差别在于取值通道——前端从 Nuxt 的runtimeConfig.public.featureFlags读取服务端渲染时由服务端把环境变量注入 runtime config再通过 Nuxt 插件以$featureFlagIsEnabled的形式 provide 给所有组件使用。六、实践小结Baserow 的特性开关体系可以归纳为一张“速查表”关注点说明开关来源环境变量FEATURE_FLAGS逗号分隔后端解析base.pystrip().lower()后存为列表后端判断feature_flag_is_enabled(FF_XXX, raise_if_disabledFalse)feature_flags.py前端判断组件内this.$featureFlagIsEnabled(FF_XXX)featureFlags.js通配符FEATURE_FLAGS*全开后端/前端/测试配置test.py均支持命名规范字母数字 短横线首尾空格自动修剪一特性一开关当前开关ai-providers、button-field新增一个特性开关的标准动作因此是后端feature_flags.py加常量 → 功能代码中用feature_flag_is_enabled判断 → 前端featureFlags.js加同名常量 → 组件中用$featureFlagIsEnabled判断 → 同步更新 feature-flags.md 中的清单。而像ai-providers这类涉及数据模型的重量级开关则需要额外准备“双状态迁移 管理命令导入 排干/重启 回滚预案”一整套升级文档这正是 Baserow 把开关说明写在开发文档里、并与测试计划文档互相引用的原因。【免费下载链接】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),仅供参考