Ecto Migrator

Polar Sponsor
爱发电 赞助
.NET 9.0

根据自然语言或模式描述生成 Ecto 迁移文件。支持处理表、列、索引、约束、引用、枚举及分区。具备可逆迁移、数据迁移及多租户模式支持。适用于在 Elixir 项目中创建或修改数据库模式、添加索引、修改表结构、创建枚举或执行数据迁移。

EctoMigration 13.

功能概述

EctoMigration 13.是一项面向实际任务的技能,主要用于General Transmigrations. from Natural Language.;Parse 用户描述并生成一个迁移文件.;

核心要点

  • Common types:: user Says. migration Action." 创建用户表,使用电子邮件和。
  • 它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。
  • 使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。

使用与执行

从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。

结果检查与注意事项

执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。该技能适合用于一次性任务,也可以接入自动化工作流,与其他技能或上层代理配合完成更完整的业务链路;在组合使用时,应明确每一步的输入输出关系,并避免不同步骤之间出现参数冲突。

Ecto Migrator

生成迁移文件

基于自然语言生成

解析用户描述并生成迁移文件。常见模式如下:

用户表述 迁移操作
“创建 users 表,包含 email 和 name 字段” create table(:users) 并定义字段
“为 users 表添加 phone 字段” alter table(:users), add :phone
“在 users 表上使 email 唯一” create unique_index(:users, [:email])
“为所有表添加 tenant_id 字段” 多个 alter table 操作,并为每个表添加索引
“将 orders 表中的 status 字段重命名为 state” rename table(:orders), :status, to: :state
“从 users 表中移除 legacy_id 字段” alter table(:users), remove :legacy_id
“为 orders 表的 amount 字段添加检查约束(amount > 0)” create constraint(:orders, ...)

文件命名规范

mix ecto.gen.migration 
# 生成路径:priv/repo/migrations/YYYYMMDDHHMMSS_.exs

命名惯例:create_

、add__to_
、create_
__index、alter_
_add_。

迁移模板

defmodule MyApp.Repo.Migrations.CreateUsers do
  use Ecto.Migration

  def change do
    create table(:users, primary_key: false) do
      add :id, :binary_id, primary_key: true
      add :email, :string, null: false
      add :name, :string, null: false
      add :role, :string, null: false, default: "member"
      add :metadata, :map, default: %{}
      add :tenant_id, :binary_id, null: false

      add :team_id, references(:teams, type: :binary_id, on_delete: :delete_all)

      timestamps(type: :utc_datetime_usec)
    end

    create unique_index(:users, [:tenant_id, :email])
    create index(:users, [:tenant_id])
    create index(:users, [:team_id])
  end
end

字段类型

完整类型映射与使用建议请参阅 references/column-types.md。

关键决策:

  • ID 字段:使用 :binary_id(UUID)—— 表定义需设 primary_key: false,手动添加 :id 字段。
  • 金额字段:使用 :integer(单位为分)或 :decimal —— 禁止使用 :float。
  • 时间戳:始终使用 timestamps(type: :utc_datetime_usec)。
  • 枚举类型:使用 :string 配合应用层的 Ecto.Enum —— 避免使用 PostgreSQL 原生 enum(难以迁移)。
  • JSON 数据:使用 :map(对应 PostgreSQL 的 jsonb 类型)。
  • 数组字段:使用 {:array, :string} 等形式。

索引策略

详细索引设计指南请参阅 references/index-patterns.md。

何时添加索引

以下情况必须添加索引:

  • 外键字段(以 _id 结尾的列)
  • tenant_id(复合索引中应作为首列)
  • 用于 WHERE 子句的字段
  • 用于 ORDER BY 的字段
  • 唯一性约束所涉及的字段

索引类型

# 标准 B-tree 索引
create index(:users, [:tenant_id])

# 唯一索引
create unique_index(:users, [:tenant_id, :email])

# 部分索引(条件索引)
create index(:orders, [:status], where: "status != 'completed'", name: :orders_active_status_idx)

# GIN 索引(用于 jsonb 字段)
create index(:events, [:metadata], using: :gin)

# GIN 索引(用于数组字段)
create index(:posts, [:tags], using: :gin)

# 复合索引
create index(:orders, [:tenant_id, :status, :inserted_at])

# 并发索引(不锁表 —— 应单独放在一个迁移中)
@disable_ddl_transaction true
@disable_migration_lock true

def change do
  create index(:users, [:email], concurrently: true)
end

约束条件

# 检查约束
create constraint(:orders, :amount_must_be_positive, check: "amount > 0")

# 排他约束(需启用 btree_gist 扩展)
execute "CREATE EXTENSION IF NOT EXISTS btree_gist", ""
create constraint(:reservations, :no_overlapping_bookings,
  exclude: ~s|gist (room_id WITH =, tstzrange(starts_at, ends_at) WITH &&)|
)

# 唯一约束(多数场景下与 unique_index 功能一致)
create unique_index(:accounts, [:slug])

引用关系(外键)

add :user_id, references(:users, type: :binary_id, on_delete: :delete_all), null: false
add :team_id, references(:teams, type: :binary_id, on_delete: :nilify_all)
add :parent_id, references(:categories, type: :binary_id, on_delete: :nothing)
on_delete 适用场景
:delete_all 子记录不能脱离父记录独立存在(例如 memberships、line items)
:nilify_all 子记录应在父记录被删除后继续存在(可选关联)
:nothing 由应用代码处理(默认行为)
:restrict 当存在子记录时,禁止删除父记录

多租户模式

每张表均需包含 tenant_id

def change do
  create table(:items, primary_key: false) do
    add :id, :binary_id, primary_key: true
    add :name, :string, null: false
    add :tenant_id, :binary_id, null: false
    timestamps(type: :utc_datetime_usec)
  end

  # 复合索引中 tenant_id 必须置于首位
  create index(:items, [:tenant_id])
  create unique_index(:items, [:tenant_id, :name])
end

为已有表添加 tenant_id

def change do
  alter table(:items) do
    add :tenant_id, :binary_id
  end

  # 在独立的数据迁移中完成数据填充(backfill),之后再执行:
  # alter table(:items) do
  #   modify :tenant_id, :binary_id, null: false
  # end
end

数据迁移

规则:禁止在同一个迁移文件中混合模式变更(schema changes)与数据变更(data changes)。

安全的数据迁移模式

defmodule MyApp.Repo.Migrations.BackfillUserRoles do
  use Ecto.Migration

  # 不要使用 schema 模块 —— 它们可能在此迁移运行后发生变更
  def up do
    execute """
    UPDATE users SET role = 'member' WHERE role IS NULL
    """
  end

  def down do
    # 数据迁移通常不可逆
    :ok
  end
end

分批数据迁移(适用于大表)

def up do
  execute """
  UPDATE users SET role = 'member'
  WHERE id IN (
    SELECT id FROM users WHERE role IS NULL LIMIT 10000
  )
  """

  # 对于超大表,建议改用 Task 或 Oban job 执行
end

可逆 vs 不可逆迁移

可逆迁移(使用 change)

以下操作可由 Ecto 自动推导反向操作:

  • create table ↔ drop table
  • add column ↔ remove column
  • create index ↔ drop index
  • rename ↔ rename

不可逆迁移(使用 up/down)

必须显式定义正向与反向逻辑:

  • modify 字段类型 —— Ecto 无法自动推断原始类型
  • execute 原生 SQL
  • 数据填充(backfills)
  • 带数据的字段删除
def up do
  alter table(:users) do
    modify :email, :citext, from: :string  # 添加 from: 可提升可逆性
  end
end

def down do
  alter table(:users) do
    modify :email, :string, from: :citext
  end
end

使用 modify 时指定 from:

Phoenix 1.7+ 支持通过 from: 实现可逆的 modify 操作:

def change do
  alter table(:users) do
    modify :email, :citext, null: false, from: {:string, null: true}
  end
end

PostgreSQL 扩展

def change do
  execute "CREATE EXTENSION IF NOT EXISTS citext", "DROP EXTENSION IF EXISTS citext"
  execute "CREATE EXTENSION IF NOT EXISTS pgcrypto", "DROP EXTENSION IF EXISTS pgcrypto"
  execute "CREATE EXTENSION IF NOT EXISTS pg_trgm", "DROP EXTENSION IF EXISTS pg_trgm"
end

枚举类型(PostgreSQL 原生 —— 谨慎使用)

优先使用 :string 字段配合 Ecto.Enum。若必须使用 PostgreSQL 原生 enum:

def up do
  execute "CREATE TYPE order_status AS ENUM ('pending', 'confirmed', 'shipped', 'delivered')"

  alter table(:orders) do
    add :status, :order_status, null: false, default: "pending"
  end
end

def down do
  alter table(:orders) do
    remove :status
  end

  execute "DROP TYPE order_status"
end

警告:向 PostgreSQL enum 中新增值需使用 ALTER TYPE ... ADD VALUE,该语句无法在事务内执行。因此更推荐使用 :string + Ecto.Enum 方案。

检查清单

  • 主键:设置 primary_key: false,并手动添加 add :id, :binary_id, primary_key: true
  • 必填字段需声明 null: false
  • 使用 timestamps(type: :utc_datetime_usec)
  • 外键需配置合适的 on_delete 行为
  • 每个外键字段都应建索引
  • tenant_id 字段必须建索引(且在复合索引中作为首列)
  • 在必要位置添加唯一性约束
  • 并发索引应置于独立迁移中,并添加 @disable_ddl_transaction true
  • 数据迁移必须与模式迁移分离,存于不同文件

相关专题

更多
Postman身份认证怎么配置
Postman身份认证怎么配置

本专题从实际API接口调试场景出发,讲解Postman身份认证的完整配置流程,包括常见认证协议介绍、授权参数设置、访问令牌填写、OAuth 2.0授权及认证失败排查,帮助用户正确完成接口授权与访问验证。

2026.11.06

0

12

Postman请求头Headers怎么设置
Postman请求头Headers怎么设置

围绕Postman HTTP请求头配置展开,讲解Headers选项的具体使用方式,包括Key和Value参数填写、请求头信息添加、常见Header字段设置及请求头修改方法,帮助用户解决接口调试过程中遇到的请求头配置问题。

2026.11.06

0

13

Postman接口请求发送教程
Postman接口请求发送教程

详细介绍Postman接口请求的创建与发送方法,涵盖GET和POST请求、URL配置、请求参数、Headers请求头、Body请求体设置以及响应结果查看,帮助用户掌握Postman接口请求的完整操作流程。

2026.11.06

0

10

DBeaver怎么导入数据
DBeaver怎么导入数据

DBeaver数据导入专题,整理Excel、CSV、SQL、TXT等常见文件的数据导入方法,涵盖目标数据库选择、数据表创建、字段映射、数据类型设置及导入参数配置等操作,帮助用户将本地文件中的数据写入数据库,并了解批量导入、重复数据处理和导入失败等常见问题的解决方法。

2026.11.05

0

12

DBeaver安全防护教程大全
DBeaver安全防护教程大全

DBeaver安全防护专题,围绕数据库连接安全、账号密码保护和访问权限管理展开,整理SSL/TLS加密连接、SSH隧道、数据库凭据保存及证书验证等配置方法,同时介绍敏感信息保护、远程连接风险和高权限账号使用等注意事项,帮助用户提高数据库日常管理的安全性。

2026.11.05

0

12

DBeaver连接创建与配置教程
DBeaver连接创建与配置教程

本专题聚焦DBeaver数据库连接配置与管理,覆盖从新建连接、选择数据库类型到填写连接参数和验证连接的完整流程。针对MySQL、PostgreSQL、SQL Server等常见数据库,整理相应的连接设置方法,并提供驱动缺失、认证失败和连接异常等问题的排查方向。

2026.11.04

0

16

XORM框架结构体映射与表结构同步
XORM框架结构体映射与表结构同步

本专题围绕XORM框架的结构体映射展开,说明表名与字段的命名策略、xorm标签常用属性、主键自增与时间字段自动填充,并演示Sync2自动建表、增量字段升级、索引声明与反向生成结构体的完整流程。

2026.11.04

0

15

XORM框架安装配置与数据库连接
XORM框架安装配置与数据库连接

本专题聚焦XORM框架的配置与连接环节,拆解MySQL、PostgreSQL、SQLite、SQL Server的DSN写法与驱动选择,讲清连接池参数、多数据源拆分、读写分离与超时重连的处理方式,并补充容器与兼容数据库的适配经验。

2026.11.04

0

15

XORM框架安装配置与数据库连接
XORM框架安装配置与数据库连接

本专题聚焦XORM框架的配置与连接环节,拆解MySQL、PostgreSQL、SQLite、SQL Server的DSN写法与驱动选择,讲清连接池参数、多数据源拆分、读写分离与超时重连的处理方式,并补充容器与兼容数据库的适配经验。

2026.11.04

0

16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 134.1万人学习