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

Ecto迁移修改与回滚问题:如何保留测试数据并更新Schema?

问题解答

一、能否保留测试数据并更新Schema?

可以保留测试数据,但不建议直接修改已执行过的create_products迁移文件——迁移文件设计上应是不可变的,直接修改会导致本地迁移记录与数据库中的版本不一致,后续极易引发数据同步问题。正确操作方式如下:

  1. 新建一个专门用于添加字段的迁移文件:
    mix ecto.gen.migration add_importer_id_to_products -r Mirror.Repo
    
  2. 在生成的迁移文件中编写添加字段的逻辑:
    defmodule Mirror.Repo.Migrations.AddImporterIdToProducts do
      use Ecto.Migration
    
      def change do
        add :importer_id, :string, table: :products
      end
    end
    
  3. 执行迁移,此操作不会丢失现有测试数据:
    mix ecto.migrate -r Mirror.Repo
    
  4. 同步更新对应的Product Schema,添加新字段并修改changeset:
    defmodule Mirror.Product do
      use Ecto.Schema
      import Ecto.Changeset
    
      schema "products" do
        field :importer_id, :string # 新增字段
        field :title, :string
        field :cid, :string
        field :seller_cids, :string
        # 其他原有字段
      end
    
      def changeset(product, attrs) do
        product
        |> cast(attrs, [:importer_id, :title, :cid, :seller_cids])
        # 原有验证规则
      end
    end
    

若已修改原迁移文件且未推送到团队仓库/其他环境,也可通过回滚重执行的方式调整,但这会清空products表的测试数据,不推荐:

# 回滚2个版本,会删除products和pictures表
mix ecto.rollback -n 2 -r Mirror.Repo
# 重新执行所有迁移
mix ecto.migrate -r Mirror.Repo

二、能否直接修改create_products并回滚create_pictures?

关于回滚create_pictures

可以单独回滚create_pictures迁移,因为它是最后执行的版本,执行命令:

mix ecto.rollback -n 1 -r Mirror.Repo

此操作仅会删除pictures表,不会影响products表的测试数据。

关于修改create_products并回滚

不建议这么做,核心原因:

  1. create_pictures迁移大概率依赖products表(比如外键关联),直接回滚create_products会因表依赖或关联数据存在而失败。
  2. 修改已执行的迁移文件会破坏迁移的可追溯性,导致不同环境的迁移版本不一致,后续维护风险极高。

若确实需要调整products表结构,优先采用新增迁移文件的方式(如第一部分所述),既能保留测试数据,又能保证迁移流程的一致性。

内容的提问来源于stack exchange,提问作者Chen Yu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 13:01:08