如何在Ecto中定义无迁移、不持久化的虚拟模型?
在Ecto中创建无需持久化的虚拟模型
当然可以!在Ecto里完全能实现这种不需要迁移文件、也不持久化到数据库的「虚拟模型」,正好匹配你在iex中测试独立函数的需求。核心就是用embedded_schema来定义——你提到的embedded schema确实是实现这种需求的最佳方案,它本身就设计为不需要对应数据库表,下面给你一步步演示具体实现:
1. 定义虚拟模型
直接用embedded_schema创建模型,不需要任何迁移文件,所有字段都不会被持久化到数据库。你还可以根据需要添加virtual: true的字段,或者普通字段都没问题:
defmodule VirtualTestModel do use Ecto.Schema import Ecto.Changeset embedded_schema do # 普通字段(不会存数据库) field :name, :string field :age, :integer # 虚拟字段,仅在内存中存在 field :greeting, :string, virtual: true end # 定义changeset用于数据校验和转换 def changeset(model, params \\ %{}) do model |> cast(params, [:name, :age]) |> validate_required([:name]) |> validate_number(:age, greater_than: 0) # 可以在changeset里给虚拟字段赋值 |> put_change(:greeting, "Hello from virtual model!") end end
2. 在iex中测试使用
你可以直接在iex里加载这个模型(如果是在项目里,直接启动iex即可;如果是临时测试,也可以把代码粘贴到iex中),然后用它来测试你的独立函数:
# 创建空模型实例 empty_model = %VirtualTestModel{} # 用参数生成校验后的changeset valid_changeset = VirtualTestModel.changeset(empty_model, %{name: "Bob", age: 28}) valid_changeset.valid? # 返回 true valid_changeset.changes # 查看处理后的字段值 # 将changeset转换为可用的模型实例 processed_model = Ecto.Changeset.apply_changes(valid_changeset) processed_model.greeting # 输出 "Hello from virtual model!" # 测试你的独立函数示例 defmodule MyBusinessLogic do def format_user_info(user) do "#{user.name} is #{user.age} years old - #{user.greeting}" end end MyBusinessLogic.format_user_info(processed_model) # 输出 "Bob is 28 years old - Hello from virtual model!"
关键说明
embedded_schema不需要依赖任何数据库连接,也不需要创建迁移文件,完全在内存中运行,非常适合快速测试。- 你可以像使用普通Ecto Schema一样定义changeset,做数据校验、字段转换,完美模拟真实场景下的数据处理逻辑。
- 如果只是临时测试,甚至不需要把模型写到项目文件里,直接在iex中定义后就能使用。
内容的提问来源于stack exchange,提问作者script
相关产品推荐
相关产品推荐

