如何通过算法修改ecto中的字段

时间:2017-07-28 14:55:19

标签: database postgresql elixir ecto

大家好我正在寻找改变字段类型并在此期间转换其值的方法 我的意思是这样的:

def up do
  alter table(:users) do
    modify :role, :integer, default: fragment("convertion_function")
  end
end

我知道Ecto.Migration#modify/3函数获取 &fragment/1 参数。但它只有一个论点 有谁知道是否可以将当前值传递给 &fragment/1 函数?
或者也许有人知道更好的方法吗?

2 个答案:

答案 0 :(得分:2)

在PostgreSQL中,可以通过为USING查询指定ALTER TABLE <table> ALTER COLUMN <column>子句来完成此操作。在Ecto的迁移中我找不到任何支持。您可以使用execute执行原始查询来执行此操作。以下是如何将posts表的title列从字符串更改为整数,并将新值设置为原始标题的长度:

def up do
  execute """
    alter table posts
      alter column title
        type integer
        using length(title);
  """
end

length(title)是计算新值的片段表达式。

您也希望为反向迁移编写类似的查询。

您可以在USING here中详细了解ALTER TABLE

答案 1 :(得分:0)

default会设置新行的默认值,它与现有数据的转换无关。

AFAIK,没有办法修改列类型而不会丢失PostgreSQL / MySQL中的数据。唯一的方法是使用迁移#1创建新列,使用迁移#2迁移现有数据并删除旧列+使用迁移#3将新列重命名为旧名称。