据 AlphaMoat 统计,截至 2026-09,Ecto Migrator 累计下载 2,557 次、获 1 个星标,在全部 5,078 个 AI 技能中排名第 4,053 位,在「开发编程」分类(577 个)中排名第 504 位。
| 平台 | 累计安装 | 累计下载 | 星标 | 评论 |
|---|---|---|---|---|
| ClawHub ↗ | 76 | 2,362 | 1 | - |
| SkillHub ↗ | 156 | 2,557 | 1 | — |
各平台的计数口径不同,统计时间不一致。
可草拟表、列、索引、约束、引用关系和数据迁移。生成内容可能包含删除表列、重命名或级联删除,并可能锁定大型生产表;应用前应审查破坏性操作、备份、上线策略和回滚行为。 执行需要适当 Elixir/Ecto 项目和 Repo/数据库配置,起草本身不应用变更。schema 与 data 分离,适当时并发索引独立迁移,无法推断回滚的操作显式定义 up/down。down 函数不保证恢复已删或覆盖数据,应结合备份验证回滚。
资料发布于 2026-10-27
以下是根据技能文档生成的示例,不代表实际运行结果。
2026-09 起统计方法调整:同名技能按作者分别统计,并覆盖全部技能。图中虚线为调整前的月份,与之后的数据不直接比较,也不计算跨越调整的增长。
| 月份 | 累计下载 | 环比 | 星标 |
|---|---|---|---|
| 2026-09 | 2,557 | — | 1 |
| 2026-08 | 2,285 | +3.4% | 1 |
| 2026-07 | 2,210 | +8.9% | 1 |
| 2026-06 | 2,029 | +4.1% | 1 |
| 2026-05 | 1,950 | — | 1 |
| 2026-03 | 1,738 | — | 1 |
以下是作者发布的原始文件,按纯文本显示,本站未做修改或审核;其中的链接不可点击,命令请核实后再运行。抓取于 2026-10-23。
--- name: ecto-migrator description: "Generate Ecto migrations from natural language or schema descriptions. Handles tables, columns, indexes, constraints, references, enums, and partitioning. Supports reversible migrations, data migrations, and multi-tenant patterns. Use when creating or modifying database schemas, adding indexes, altering tables, creating enums, or performing data migrations in an Elixir project." --- # Ecto Migrator ## Generating Migrations ### From Natural Language
Parse the user's description and generate a migration file. Common patterns:
| User Says | Migration Action |
|-----------|-----------------|
| "Create users table with email and name" | `create table(:users)` with columns |
| "Add phone to users" | `alter table(:users), add :phone` |
| "Make email unique on users" | `create unique_index(:users, [:email])` |
| "Add tenant_id to all tables" | Multiple `alter table` with index |
| "Rename status to state on orders" | `rename table(:orders), :status, to: :state` |
| "Remove the legacy_id column from users" | `alter table(:users), remove :legacy_id` |
| "Add a check constraint on orders amount > 0" | `create constraint(:orders, ...)` |
### File Naming
```bash
mix ecto.gen.migration <name>
# Generates: priv/repo/migrations/YYYYMMDDHHMMSS_<name>.exs
```
Name conventions: `create_<table>`, `add_<column>_to_<table>`, `create_<table>_<column>_index`, `alter_<table>_add_<columns>`.
## Migration Template
```elixir
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
```
## Column Types
See [references/column-types.md](references/column-types.md) for complete type mapping and guidance.
Key decisions:
- **IDs**: Use `:binary_id` (UUID) — set `primary_key: false` on table, add `:id` manually.
- **Money**: Use `:integer` (cents) or `:decimal` — never `:float`.
- **Timestamps**: Always `timestamps(type: :utc_datetime_usec)`.
- **Enums**: Use `:string` with app-level `Ecto.Enum` — avoid Postgres enums (hard to migrate).
- **JSON**: Use `:map` (maps to `jsonb`).
- **Arrays**: Use `{:array, :string}` etc.
## Index Strategies
See [references/index-patterns.md](references/index-patterns.md) for detailed index guidance.
### When to Add Indexes
Always index:
- Foreign keys (`_id` columns)
- `tenant_id` (first column in composite indexes)
- Columns used in `WHERE` clauses
- Columns used in `ORDER BY`
- Unique constraints
### Index Types
```elixir
# Standard B-tree
create index(:users, [:tenant_id])
# Unique
create unique_index(:users, [:tenant_id, :email])
# Partial (conditional)
create index(:orders, [:status], where: "status != 'completed'", name: :orders_active_status_idx)
# GIN for JSONB
create index(:events, [:metadata], using: :gin)
# GIN for array columns
create index(:posts, [:tags], using: :gin)
# Composite
create index(:orders, [:tenant_id, :status, :inserted_at])
# Concurrent (no table lock — use in separate migration)
@disable_ddl_transaction true
@disable_migration_lock true
def change do
create index(:users, [:email], concurrently: true)
end
```
## Constraints
```elixir
# Check constraint
create constraint(:orders, :amount_must_be_positive, check: "amount > 0")
# Exclusion constraint (requires btree_gist extension)
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 constraint (same as unique_index for most purposes)
create unique_index(:accounts, [:slug])
```
## References (Foreign Keys)
```elixir
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` | Use When |
|-------------|----------|
| `:delete_all` | Child can't exist without parent (memberships, line items) |
| `:nilify_all` | Child should survive parent deletion (optional association) |
| `:nothing` | Handle in application code (default) |
| `:restrict` | Prevent parent deletion if children exist |
## Multi-Tenant Patterns
### Every Table Gets tenant_id
```elixir
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
# Always composite index with tenant_id first
create index(:items, [:tenant_id])
create unique_index(:items, [:tenant_id, :name])
end
```
### Adding tenant_id to Existing Tables
```elixir
def change do
alter table(:items) do
add :tenant_id, :binary_id
end
# Backfill in a separate data migration, then:
# alter table(:items) do
# modify :tenant_id, :binary_id, null: false
# end
end
```
## Data Migrations
**Rule: Never mix schema changes and data changes in the same migration.**
### Safe Data Migration Pattern
```elixir
defmodule MyApp.Repo.Migrations.BackfillUserRoles do
use Ecto.Migration
# Don't use schema modules — they may change after this migration runs
def up do
execute """
UPDATE users SET role = 'member' WHERE role IS NULL
"""
end
def down do
# Data migrations may not be reversible
:ok
end
end
```
### Batched Data Migration (large tables)
```elixir
def up do
execute """
UPDATE users SET role = 'member'
WHERE id IN (
SELECT id FROM users WHERE role IS NULL LIMIT 10000
)
"""
# For very large tables, use a Task or Oban job instead
end
```
## Reversible vs Irreversible
### Reversible (use `change`)
These are auto-reversible:
- `create table` ↔ `drop table`
- `add column` ↔ `remove column`
- `create index` ↔ `drop index`
- `rename` ↔ `rename`
### Irreversible (use `up`/`down`)
Must define both directions:
- `modify` column type — Ecto can't infer the old type
- `execute` raw SQL
- Data backfills
- Dropping columns with data
```elixir
def up do
alter table(:users) do
modify :email, :citext, from: :string # from: helps reversibility
end
end
def down do
alter table(:users) do
modify :email, :string, from: :citext
end
end
```
### Using `modify` with `from:`
Phoenix 1.7+ supports `from:` for reversible `modify`:
```elixir
def change do
alter table(:users) do
modify :email, :citext, null: false, from: {:string, null: true}
end
end
```
## PostgreSQL Extensions
```elixir
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
```
## Enum Types (PostgreSQL native — use sparingly)
Prefer `Ecto.Enum` with `:string` columns. If you must use Postgres enums:
```elixir
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
```
**Warning:** Adding values to Postgres enums requires `ALTER TYPE ... ADD VALUE` which cannot run inside a transaction. Prefer `:string` + `Ecto.Enum`.
## Checklist
- [ ] Primary key: `primary_key: false` + `add :id, :binary_id, primary_key: true`
- [ ] `null: false` on required columns
- [ ] `timestamps(type: :utc_datetime_usec)`
- [ ] Foreign keys with appropriate `on_delete`
- [ ] Index on every foreign key column
- [ ] `tenant_id` indexed (composite with lookup fields)
- [ ] Unique constraints where needed
- [ ] Concurrent indexes in separate migration with `@disable_ddl_transaction true`
- [ ] Data migrations in separate files from schema migrations
用 gh 命令行工具查看 GitHub 上的 PR 检查、工作流运行与 API 查询的技能。
聚合 16 个搜索引擎、无需 API Key 的检索技能。
用命令行直接列出、配置、授权并调用 MCP 服务与工具。
生成有效的 Mermaid 图表,如流程图、时序图、思维导图、ER 图、用户旅程等。
用受管 OAuth 访问 YouTube Data API,检索视频并管理频道内容。
通过受管的 OAuth 连接访问 GitHub REST API。
覆盖规划、实现、验证与测试的编码工作流技能。
整理 Docker 常用命令与容器工作流的技能。
数据月份:2026-09 · 下载/星标/安装数聚合自公开技能注册库(ClawHub、SkillHub),按月更新。口径说明见数据方法。