将家庭相册从 Synology Photos 迁移到自托管 Immich 实例的个人操作手册。 涵盖批量上传、Google Takeout 导入,以及通过 Synology PostgreSQL 数据库重建相册。
环境说明#
- 来源:运行 Synology Photos 的 Synology NAS(多用户)
- 目标:同一 NAS 上自托管的 Immich
- 上传工具:immich-go v0.31+
- 客户端:Windows 上的 WSL2,SSH 访问 NAS
- 相册脚本:自定义 Python(
migrate_albums.py),使用 Immich REST API
第一阶段:照片上传#
策略#
每位用户有两个来源:
- Google Takeout — 截止日期之前的照片(以 Google Photos 为主要存储时)
- Synology 文件夹 — 截止日期之后的照片(切换到 Synology 作为主存储后)
截止日期即你从 Google Photos 切换到 Synology 作为主要相册存储的时间点。此前的照片以完整分辨率存在 Google Photos 中;此后的原始分辨率在 Synology 上。
immich-go 文件夹上传#
直接在 NAS 上运行 — 避免将大型相册(100 GB+)通过网络传输。
| |
关键参数:
| 参数 | 用途 |
|---|---|
--manage-raw-jpeg=StackCoverJPG | 将 RAW+JPEG 对堆叠,以 JPEG 为封面 |
--manage-burst=Stack | 堆叠连拍序列 |
--pause-immich-jobs=true | 上传期间暂停 ML 任务(更快) |
--session-tag | 用会话 ID 标记所有上传,便于追踪 |
--concurrent-tasks=6 | 并发数 — 根据 NAS CPU 调整 |
--on-errors=continue | 单文件失败时不中止整体 |
将文件夹直接作为相册上传:
| |
Google Takeout 导入#
下载 Takeout 归档后:
| |
使用 --date-range=<start>,<cutoff> 限制截止日期之前的照片(避免导入已在 Synology 上存有原始分辨率的 Google 压缩版本)。
第二阶段:重建相册#
Synology Photos 将相册成员关系存储在 PostgreSQL 数据库中。照片上传到 Immich 后,通过读取 Synology 数据库 TSV 导出的脚本,利用 Immich REST API 重建相册。
从 Synology 数据库导出相册数据#
Synology Photos 使用 PostgreSQL,数据库名为 synofoto。必须以 postgres 用户运行(peer 认证 — 无密码,但需要 sudo)。
| |
注意: Synology 上的旧版 psql 不支持
--csv,使用-A -F$'\t' -t输出 TSV 格式。
关键数据表:
| 表 | 用途 |
|---|---|
album | 相册元数据(名称、所有者、共享标志) |
normal_album | 标记为普通(非智能)类型的相册 |
many_item_has_many_normal_album | 相册 ↔ 照片成员关系 |
item | 照片条目(逻辑层,unit 的父级) |
unit | 物理文件(文件名、拍摄时间、文件夹外键) |
folder | 文件夹路径 |
user_info | 用户显示名称 |
从数据库字段构建物理路径:
- 个人空间:
/volume1/homes/<username>/Photos<folder_path>/<filename> - 共享空间:
/volume1/photo<folder_path>/<filename>
TSV 字段(10 列,制表符分隔):
| |
相册迁移脚本#
migrate_albums.py 读取 TSV 并在 Immich 中重建所有相册:
- 对每张照片,调用
POST /api/search/metadata,参数为originalFileName - 如有多个文件名匹配,选择
takentime最接近的(Synology 数据库的 Unix 时间戳) - 以相册所有者账号通过
POST /api/albums创建相册 - 通过
PUT /api/albums/{id}/assets批量(每批 100 个)添加资产 - 通过
PUT /api/albums/{id}/users将相册共享给家庭成员(editor 角色)
脚本顶部配置块:
| |
用法:
| |
重要说明:
- 脚本在创建前检查相册名称是否已存在 — 重复运行安全,但如果绕过检查会创建重复项
- 没有配置 API key 的照片所有者会被跳过并报告;补充 key 后重新运行即可
- 未匹配的照片(尚未上传)会被打印出来,但不阻塞其他相册的处理
- 搜索按 Immich 用户隔离,因此照片查找必须使用文件所有者的 API key,而非相册所有者的
验证#
迁移完成后,对比 Synology 和 Immich 之间的相册照片数量:
在 Synology 数据库中查询每个相册的 COUNT(*),与 GET /api/albums/{id} 返回的 assetCount 字段对比。
经验总结#
- 在 NAS 上运行 immich-go — 无网络瓶颈;对 100 GB+ 的相册库至关重要
- 上传期间暂停 Immich ML 任务 —
--pause-immich-jobs=true显著提升导入速度 - immich-go 自动处理重复 — 重复运行安全;已上传的文件会被检测并跳过
- 每个 Immich 用户需要独立的 API key — 相册成员搜索必须使用文件所有者的 key(搜索结果按用户隔离)
- 文件名 + 拍摄时间匹配可靠 —
originalFileName搜索加 Unix 时间戳消歧,对 Synology Photos 数据集效果很好 - Synology 上的旧版 psql — 没有
--csv参数;使用-A -F$'\t' -t输出 TSV - immich-go 的
--session-tag— 用会话 ID 标记所有上传,便于审计哪些文件来自哪次运行 - 相册脚本幂等性 — 创建前检查已有相册名称;未匹配的照片不阻塞其他处理