You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Strapi+MySQL+S3环境下导入Dev库时如何保留Prod文件元数据并同步新媒体

Strapi v4 + MySQL + S3 环境下安全导入开发媒体数据的方案

针对你遇到的开发环境数据导入生产时覆盖files表、丢失媒体元数据的问题,以下是几种可落地的通用实践:

方案一:MySQL 基于唯一键的增量导入(推荐自动化)

利用MySQL的INSERT ... ON DUPLICATE KEY UPDATE语法,实现仅新增生产环境不存在的媒体记录,保留现有生产数据:

  1. 添加唯一索引
    在生产环境的strapi_files表中,针对S3对象键(key字段)或文件哈希值(file_hash字段)创建唯一索引,确保能识别重复的媒体文件:

    ALTER TABLE strapi_files ADD UNIQUE INDEX idx_unique_file_key (`key`);
    -- 或用file_hash:ALTER TABLE strapi_files ADD UNIQUE INDEX idx_unique_file_hash (`file_hash`);
    
  2. 导出开发环境的媒体表
    使用mysqldump单独导出开发环境的strapi_files及关联表(如strapi_upload_file_related_morph):

    mysqldump -u [DEV_DB_USER] -p [DEV_DB_NAME] strapi_files strapi_upload_file_related_morph > dev_media_dump.sql
    
  3. 修改导出的SQL脚本
    打开导出的dev_media_dump.sql,将所有INSERT INTO语句修改为带ON DUPLICATE KEY UPDATE的格式,重复记录不做任何更新:

    -- 原语句:INSERT INTO strapi_files (id, key, file_hash, ...) VALUES (...);
    -- 修改后:
    INSERT INTO strapi_files (id, key, file_hash, ...) VALUES (...) 
    ON DUPLICATE KEY UPDATE id = id; -- 保留生产环境现有记录,不覆盖
    
    -- 关联表同理,针对关联唯一键(如file_id + related_id + related_type)设置唯一索引后,同样用ON DUPLICATE KEY UPDATE跳过重复
    
  4. 导入到生产环境
    执行修改后的SQL脚本完成增量导入:

    mysql -u [PROD_DB_USER] -p [PROD_DB_NAME] < dev_media_dump.sql
    

方案二:Strapi 自定义迁移脚本(贴合CMS架构)

通过Strapi的数据库查询API编写脚本,精准同步增量媒体数据,避免直接操作数据库的风险:

  1. 开发环境导出增量媒体
    编写Node.js脚本,从开发环境获取所有媒体记录,过滤掉生产环境已存在的条目(通过key或file_hash判断):

    // 开发环境运行的脚本
    const strapi = require('@strapi/strapi');
    const fs = require('fs');
    
    async function exportIncrementalMedia() {
      await strapi().load();
      // 获取开发所有媒体
      const devFiles = await strapi.db.query('plugin::upload.file').findMany({
        populate: ['related'],
      });
      // 假设已通过API或数据库查询获取生产环境的所有file_key列表
      const prodFileKeys = await fetchProdFileKeys(); // 自行实现该函数
    
      // 过滤出生产不存在的媒体
      const incrementalFiles = devFiles.filter(file => !prodFileKeys.includes(file.key));
      fs.writeFileSync('incremental_media.json', JSON.stringify(incrementalFiles));
    }
    
    exportIncrementalMedia();
    
  2. 生产环境导入增量媒体
    在生产环境运行脚本,将过滤后的媒体数据插入数据库,同时确保S3文件已同步:

    // 生产环境运行的脚本
    const strapi = require('@strapi/strapi');
    const fs = require('fs');
    
    async function importIncrementalMedia() {
      await strapi().load();
      const incrementalFiles = JSON.parse(fs.readFileSync('incremental_media.json', 'utf8'));
    
      for (const file of incrementalFiles) {
        // 插入媒体记录
        await strapi.db.query('plugin::upload.file').create({
          data: {
            key: file.key,
            file_hash: file.file_hash,
            name: file.name,
            mime: file.mime,
            // 其他必填字段...
          },
        });
        // 插入关联记录(如果有)
        for (const related of file.related) {
          await strapi.db.query('plugin::upload.file').createRelations({
            where: { id: file.id },
            relation: 'related',
            values: related.id,
          });
        }
      }
    }
    
    importIncrementalMedia();
    
  3. 同步S3文件
    在导入数据库前,先将开发环境S3桶的新增文件同步到生产桶:

    aws s3 sync s3://dev-strapi-uploads s3://prod-strapi-uploads --delete --exclude "*" --include "uploads/**/*"
    

方案三:拆分备份与导入流程

将数据库备份拆分为普通内容和媒体内容两部分,分别处理:

  1. 全量导入非媒体表
    导出开发环境除strapi_files和关联表外的所有表,直接导入生产:

    mysqldump -u [DEV_DB_USER] -p [DEV_DB_NAME] --ignore-table=[DEV_DB_NAME].strapi_files --ignore-table=[DEV_DB_NAME].strapi_upload_file_related_morph > dev_content_dump.sql
    mysql -u [PROD_DB_USER] -p [PROD_DB_NAME] < dev_content_dump.sql
    
  2. 增量导入媒体表

    • 先从生产环境导出所有媒体的唯一标识(如key):
      mysql -u [PROD_DB_USER] -p [PROD_DB_NAME] -e "SELECT key FROM strapi_files;" > prod_file_keys.txt
      
    • 导出开发环境中生产不存在的媒体记录:
      mysqldump -u [DEV_DB_USER] -p [DEV_DB_NAME] strapi_files strapi_upload_file_related_morph --where="key NOT IN ('$(paste -s -d "','" prod_file_keys.txt)')" > dev_incremental_media.sql
      
    • 将增量媒体导入生产环境:
      mysql -u [PROD_DB_USER] -p [PROD_DB_NAME] < dev_incremental_media.sql
      

关键注意事项

  • 主键冲突处理:若开发与生产的files表id字段有重复,导入时可去掉SQL中的id值,让MySQL自动生成新的自增主键,避免冲突。
  • 关联表同步:务必同步strapi_upload_file_related_morph表的增量记录,否则内容与媒体的关联会失效。
  • Jenkins自动化:将上述步骤封装为Shell脚本或Jenkinsfile阶段,集成到CI/CD流水线中,实现一键安全部署。

内容的提问来源于stack exchange,提问作者keerthi m

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 00:43:12