Mealie v1 迁移指南:从旧版导出备份到新实例的完整实操与源码解析
2026/9/15 18:22:26 网站建设 项目流程

Mealie v1 迁移指南:从旧版导出备份到新实例的完整实操与源码解析

【免费下载链接】mealieMealie is a self hosted recipe manager and meal planner with a RestAPI backend and a reactive frontend application built in Vue for a pleasant user experience for the whole family. Easily add recipes into your database by providing the url and mealie will automatically import the relevant data or add a family recipe with the UI editor项目地址: https://gitcode.com/GitHub_Trending/me/mealie

Mealie 的 v1 版本从底层重构了数据模型、API 与权限体系,旧版数据无法直接平滑升级。本文基于官方迁移文档,完整讲解"旧实例导出备份 → 新实例导入迁移 → 校验报告"的四步迁移路径,并深入剖析仓库内MealieAlphaMigrator迁移器的字段映射、报告机制与图片导入实现,帮助你安全、快速地把旧版食谱数据搬进 v1 实例。

迁移前必须了解的三件事

v1 发布版本应当被视为一个全新的应用:大量改动提升了应用性能与开发者体验,但也带来了无法回避的破坏性变更。在动手迁移之前,请先确认以下三点:

  1. API 集成将被破坏:v1 中多个 API 端点已经变化。如果你依赖旧版 API 编写了外部脚本或集成代码,必须改用新的端点。
  2. 食谱默认私有:v1 中食谱默认只能被登录用户查看。你可以精细配置公开访问,也可以让实例保持完全私有。详见权限与公开访问指南。
  3. 迁移支持范围有限:目前迁移工具只覆盖以下数据类型,其余类型(如用户、分组、饮食计划、Cookbook/页面)仍在开发中:
数据类型迁移支持状态
Recipes(食谱)✅ 已支持
Categories(分类)✅ 已支持
Tags(标签)✅ 已支持
Users(用户)❌ 未支持
Groups(分组)❌ 未支持
Meal Plans(饮食计划)❌ 未支持
Cookbooks / Pages(食谱簿/页面)❌ 未支持

官方说明:支持更多数据类型的工作正在推进中,但并非当前优先级,欢迎通过 PR 贡献额外数据的迁移支持。

Step 1:搭建全新 v1 实例

考虑到升级的本质,强烈建议在现有实例旁边并行搭建一个新的 v1 实例,而不是在旧实例上原地升级。这样可以安全、快速地进行数据迁移,且不会影响正在运行的旧服务。

按照安装清单完成新实例的搭建并成功登录后,再继续进入 Step 2。

从仓库结构看,v1 采用了docker-compose.ymlDockerfile等标准的容器化部署方式,同时支持通过uv.lockpyproject.toml管理 Python 依赖,新实例与旧实例可在不同端口/目录下并存运行。

Step 2:从 Pre-v1 旧实例导出数据

在旧版(pre-v1)实例中,进入Admin 管理后台,找到标记为"Backups"的区块(如上图所示),执行一次数据导出(备份)

导出时请注意:

  • 务必勾选包含食谱(recipes),这是迁移所需的核心数据;
  • 勾选其他额外项目不会影响迁移流程,但即便包含它们也会被迁移器忽略(因为迁移器只解析食谱、分类与标签相关的数据);
  • 导出产物是一个.zip归档文件,请妥善保存。

从前端迁移页面展示的目录树(见 migrations.vue)可以确认,旧版备份包的内部结构大致如下:

mealie.zip └── recipes/ ├── recipe-name/ │ ├── recipe-name.json # 食谱元数据 │ └── images/ │ ├── original.webp │ ├── full.jpg │ └── thumb.jpg └── recipe-name-1/ ├── recipe-name-1.json └── images/ ...

其中recipe-name.json为食谱数据文件,images目录存放该食谱的图片(原图、全尺寸图与缩略图)。

Step 3:使用迁移工具导入 v1 实例

在新 v1 实例中按以下步骤操作:

  1. 浏览器访问/group/migrations页面;
  2. 在迁移类型下拉框中选择 "Mealie"(即 pre-v1 迁移器,前端代码中映射为mealie_alpha,见 migrations.vue);
  3. 上传第 2 步从旧实例导出的.zip备份文件;
  4. 可选:勾选"为所有导入食谱添加迁移标签"选项,迁移器会自动为导入的食谱打上mealie_alpha标签,便于事后识别与批量管理;
  5. 点击提交,迁移随即开始。整个过程可能需要一些时间;
  6. 迁移完成后,页面下方的"Previous Migrations"(历史迁移)表格中会出现一条新记录,点击查看迁移报告,确认每条食谱的导入结果。

关于迁移报告:存在个别食谱导入失败的情况,但迁移器仍会继续导入其余成功的食谱。多数情况下,手动迁移失败食谱比排查失败原因更快。若迁移工具本身出现问题,可在 GitHub 上提交 issue 反馈。

迁移前端页面的实现细节

迁移页面(frontend/app/pages/group/migrations.vue)的界面元素与后端能力一一对应:

  • 迁移类型下拉框支持 Mealie pre-v1 以及 Chowdown、CopyMeThat、MyRecipeBox、Nextcloud、Paprika、PlanToEat、RecipeKeeper、Tandoor、Cook'n 等十余种来源;
  • Mealie 迁移只接受.zip文件(acceptedFileType: ".zip");
  • 页面上用树状视图直观展示备份包的期望结构,方便你对照检查导出的压缩包格式;
  • 勾选"添加迁移标签"对应请求参数addMigrationTag
  • 提交后调用api.groupMigration.startMigration(payload)触发后端POST /groups/migrations接口,返回的ReportSummary会插入到历史迁移列表顶部。

后端的迁移入口与执行流程

后端迁移接口由 GroupMigrationController 提供,路由为POST /groups/migrations,表单参数包括:

参数类型说明
archive文件(必填)上传的 zip 备份文件,服务端会先保存到临时目录
migration_type枚举(必填)迁移来源类型,如mealie_alpha
add_migration_tag布尔(可选)是否给导入食谱添加来源标签,默认false

控制器会根据migration_typeSupportedMigrations(见 group_migration.py)映射出对应的迁移器类,并传入当前登录用户、所在分组(group)与家庭(household)上下文,然后调用迁移器的migrate()方法。整个执行过程分为三步(见 BaseMigrator):

  1. _create_report():在数据库中创建一条状态为in_progress的迁移报告;
  2. _migrate():执行实际的数据解析与导入(由各子类实现);
  3. _save_all_entries():将所有导入条目的成功/失败信息写入报告,并汇总出最终状态——全部成功为success、全部失败为failure、部分成功为partial

MealieAlphaMigrator:旧版数据的字段映射与导入

MealieAlphaMigrator(mealie_alpha.py)是本次迁移的核心实现。它做了以下几件事:

字段别名映射:旧版 JSON 字段名与 v1 新 Schema 不一致,通过key_aliases完成转换:

旧字段(alias)新字段(key)处理函数
titlename
ingredientsrecipeIngredient
directionsrecipeInstructions
tagstagssplit_by_comma(按逗号拆分、去除空白并转为首字母大写)

Schema 归一化_convert_to_new_schema):

  • categoriesrecipeCategory
  • 删除旧版内部字段_iddate_added
  • 过滤掉 tags/categories 中的空字符串元素;
  • extras为列表则重置为空字典;
  • comments置空列表;
  • id重置为None,让数据库为新食谱生成全新主键。

压缩包解压与图片搬运_migrate):迁移器将 zip 解压到临时目录,通过rglob("**/recipes/**/[!.]*.json")递归找出所有食谱 JSON 文件,逐个解析并导入数据库;导入成功后,再把原备份中该食谱images目录下的图片复制到新实例的食谱图片目录中。此外,BaseMigrator.get_zip_base_path还处理了 Safari 等工具解压产生的__MACOSX目录干扰,确保能正确定位备份包的根目录。

食谱所有者分配:执行任何迁移时,导入食谱的所有者会自动分配给执行迁移操作的用户。分组内的所有成员仍可访问该食谱,但所有者拥有特殊权限,可以锁定食谱、禁止其他用户编辑。这一逻辑在import_recipes_to_database中体现(见 _migration_base.py):每条食谱被写入user_id(当前用户)与group_id,标签与分类还会通过get_or_set_tags/get_or_set_category归并到分组现有的标签与分类体系中。

食谱默认设置的继承

迁移时,导入食谱的各项显示设置(是否公开、是否显示营养信息、是否显示素材、是否横向视图、是否禁用评论)并非硬编码,而是从当前家庭(household)的偏好设置中读取并应用到每条导入食谱上(见 _migration_base.py)。因此,导入前可以先在 v1 实例中配置好家庭偏好,迁移后的食谱会自动遵循这些默认值。

Step 4:迁移完成后的检查与收尾

迁移完成后,建议做以下检查:

  1. 查看迁移报告:确认每条食谱的状态(成功/失败),对失败条目决定是手动重建还是重新导入;
  2. 确认访问权限:由于 v1 食谱默认私有,请按需为公开食谱、分组或家庭配置公开访问。完整的判定规则(私有分组/家庭/食谱层层拦截、私密链接可绕过所有权限等)见权限与公开访问指南;
  3. 使用mealie_alpha标签:如果勾选了迁移标签,可在食谱列表中按该标签筛选,快速复核导入结果或进行批量清理;
  4. 体验 v1 新功能:v1 引入了大量新特性与改进,可通过项目的发布变更说明(仓库根目录的cliff.toml即用于生成变更日志)了解每个版本的新增内容;
  5. 确认新实例数据无误后,再逐步下线旧实例,完成整体切换。

常见问题与注意事项汇总

  • 导出包包含食谱以外的数据怎么办?会被迁移器忽略,不影响迁移流程。
  • 个别食谱导入失败怎么办?迁移报告会给出失败原因,其余成功食谱不受影响;官方建议直接手动重建失败的食谱,效率更高。
  • 图片没有迁移成功?迁移器会尝试从备份的images目录复制图片(见 migration_helpers.py 中的import_image/scrape_image),若源文件缺失或格式无法识别(UnidentifiedImageError),该食谱会保留但图片导入会被跳过并记录日志。
  • 安全提示:迁移器对备份包内的图片路径做了目录穿越防护(safe_local_path),任何试图逃逸解压根目录的路径都会被静默拒绝,避免归档文件触发任意本地文件读取。

通过以上四步,你可以把旧版 Mealie 的食谱、分类与标签数据完整搬入 v1 新实例,并在全新的权限体系与架构下继续使用。仓库中迁移相关的全部实现(迁移控制器、迁移基类、Mealie 迁移器)与前端页面(migrations.vue)均可直接查阅,作为理解或扩展迁移能力的参考。

【免费下载链接】mealieMealie is a self hosted recipe manager and meal planner with a RestAPI backend and a reactive frontend application built in Vue for a pleasant user experience for the whole family. Easily add recipes into your database by providing the url and mealie will automatically import the relevant data or add a family recipe with the UI editor项目地址: https://gitcode.com/GitHub_Trending/me/mealie

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询