我目前正在进行一系列迁移,这些迁移会创建一些带有引用和一些唯一索引的表。当我想用mix ecto.migrate
迁移表时,这似乎工作得很好但是如果我想回滚mix ecto.rollback
咳嗽以下错误。我是否需要更改迁移以在回滚期间添加处理索引的内容?
迁移步骤:
defmodule App.Repo.Migrations.CreateTokens do
use Ecto.Migration
def change do
create table(:tokens) do
add :token, :string
add :user_id, references(:users, on_delete: :delete_all, on_update: :update_all)
timestamps()
end
create index(:tokens, [:user_id])
create unique_index(:tokens, [:token], unique: true, name: :unique_tokens_index)
end
end
错误日志:
[info] == Running App.Repo.Migrations.CreateTokens.change/0 backward
[info] drop index unique_tokens_index
[info] drop index tokens_user_id_index
** (Mariaex.Error) (1553): Cannot drop index 'tokens_user_id_index': needed in a foreign key constraint
(ecto) lib/ecto/adapters/sql.ex:200: Ecto.Adapters.SQL.query!/5
(ecto) lib/ecto/adapters/mysql.ex:118: anonymous fn/4 in Ecto.Adapters.MySQL.execute_ddl/3
(elixir) lib/enum.ex:1899: Enum."-reduce/3-lists^foldl/2-0-"/3
(ecto) lib/ecto/adapters/mysql.ex:118: Ecto.Adapters.MySQL.execute_ddl/3
(ecto) lib/ecto/migration/runner.ex:104: anonymous fn/2 in Ecto.Migration.Runner.flush/0
(elixir) lib/enum.ex:1899: Enum."-reduce/3-lists^foldl/2-0-"/3
(ecto) lib/ecto/migration/runner.ex:102: Ecto.Migration.Runner.flush/0
(stdlib) timer.erl:181: :timer.tc/2
(ecto) lib/ecto/migration/runner.ex:26: Ecto.Migration.Runner.run/6
(ecto) lib/ecto/migrator.ex:128: Ecto.Migrator.attempt/6
(ecto) lib/ecto/migrator.ex:106: anonymous fn/4 in Ecto.Migrator.do_down/4
(ecto) lib/ecto/adapters/sql.ex:576: anonymous fn/3 in Ecto.Adapters.SQL.do_transaction/3
(db_connection) lib/db_connection.ex:1283: DBConnection.transaction_run/4
(db_connection) lib/db_connection.ex:1207: DBConnection.run_begin/3
(db_connection) lib/db_connection.ex:798: DBConnection.transaction/3
(ecto) lib/ecto/migrator.ex:262: anonymous fn/4 in Ecto.Migrator.migrate/4
(elixir) lib/enum.ex:1294: Enum."-map/2-lists^map/1-0-"/2
(ecto) lib/mix/tasks/ecto.rollback.ex:79: anonymous fn/4 in Mix.Tasks.Ecto.Rollback.run/2
(elixir) lib/enum.ex:737: Enum."-each/2-lists^foreach/1-0-"/2
(elixir) lib/enum.ex:737: Enum.each/2
答案 0 :(得分:0)
ecto.rollback
通常也能正常工作。通过阅读错误消息,似乎问题是ecto正在尝试回滚一个具有其他表使用的密钥作为外键的表。这可能是您的迁移订单的问题。
例如,如果您有此迁移
defmodule App.Repo.Migrations.CreateTokens do
use Ecto.Migration
def change do
create table(:tokens) do
add :token, :string
add :user_id, references(:users, on_delete: :delete_all, on_update: :update_all)
timestamps()
end
create index(:tokens, [:user_id])
create unique_index(:tokens, [:token], unique: true, name: :unique_tokens_index)
end
end
应首先创建CreateUsers
迁移(这意味着首先在文件名上设置较低的时间戳),因为CreateTokens依赖于CreateUsers
来建立其foreign_keys。
此错误可能是由于您生成迁移并尝试自己随后更改它。请记住,迁移对时间敏感/对订单敏感,因此如果您还没有创建用户表,则无法创建引用用户的令牌表
您可以尝试运行mix ecto.reset
,但由于在尝试回滚时遇到错误,因此在运行mix ecto.migrate
解决方案是修复迁移订单甚至拆分为更多迁移...例如:CreateUsers,CreateTokens,CreateForeignKeys