使用单一迁移更新数据库?
updating the database with single migration?
我有一个 table 有一个“项目”,该项目有一个采用字符串数组的字段工作区。所以我将其转换为存储单个字符
create table("projects") do
add(:name, :string, null: false)
add(:title, :string, null: false)
add(:workspaces, {:array, :string})
timestamps()
end
我编写此迁移是为了存储单个字符串
alter table(:projects) do
modify(:workspace, :string)
我想 运行 此迁移,但我还想更新存储在数据库中的所有数据。我需要更新所有工作区数据以存储单个字符串。
假设工作区是否有这个值{value1, value2}
。它将寻找 value1,如果找到它,它将存储 value1,否则它将存储 value2
这就是 {value1, value2}
它在数据库 table 中的存储方式。所以当我们将它加载到 elixir 中时,它看起来像这样 ["value1", "value2"]
我可以在这里做什么?
您似乎正试图在关系数据库中创建一个 schema-less 数据库。这很快就会变得困难。使用像 couch 或 mongo.
这样的无模式数据库可能会更好
但是,如果您使用的是 postgres,jsonb 或 json 列类型将更好地服务于此用例 IMO。数据有点难以查询,因为 postgres operators 很有趣,但一旦你仔细研究它,它就不会太糟糕,适当索引的性能将与无模式相媲美。此外,您还可以获得不必将 serializing/deserializing 写入数据库层的额外好处。
如果我没理解错的话,您想将 workspaces
数组列更改为包含数组第一个元素的 workspace
字符串列。如果是这种情况,您可以在迁移中执行类似的操作:
# Add the `workspace` column:
alter table(:projects) do
add(:workspace, :string)
end
# Set the value of the new column:
execute("""
UPDATE projects SET workspace = CASE
WHEN 'value1' = ANY(workspaces) THEN 'value1'
WHEN 'value2' = ANY(workspaces) THEN 'value2'
ELSE 'default_value'
END
""")
# Remove the old column
alter table(:projects) do
remove(:workspaces)
end
我有一个 table 有一个“项目”,该项目有一个采用字符串数组的字段工作区。所以我将其转换为存储单个字符
create table("projects") do
add(:name, :string, null: false)
add(:title, :string, null: false)
add(:workspaces, {:array, :string})
timestamps()
end
我编写此迁移是为了存储单个字符串
alter table(:projects) do
modify(:workspace, :string)
我想 运行 此迁移,但我还想更新存储在数据库中的所有数据。我需要更新所有工作区数据以存储单个字符串。
假设工作区是否有这个值{value1, value2}
。它将寻找 value1,如果找到它,它将存储 value1,否则它将存储 value2
这就是 {value1, value2}
它在数据库 table 中的存储方式。所以当我们将它加载到 elixir 中时,它看起来像这样 ["value1", "value2"]
我可以在这里做什么?
您似乎正试图在关系数据库中创建一个 schema-less 数据库。这很快就会变得困难。使用像 couch 或 mongo.
这样的无模式数据库可能会更好但是,如果您使用的是 postgres,jsonb 或 json 列类型将更好地服务于此用例 IMO。数据有点难以查询,因为 postgres operators 很有趣,但一旦你仔细研究它,它就不会太糟糕,适当索引的性能将与无模式相媲美。此外,您还可以获得不必将 serializing/deserializing 写入数据库层的额外好处。
如果我没理解错的话,您想将 workspaces
数组列更改为包含数组第一个元素的 workspace
字符串列。如果是这种情况,您可以在迁移中执行类似的操作:
# Add the `workspace` column:
alter table(:projects) do
add(:workspace, :string)
end
# Set the value of the new column:
execute("""
UPDATE projects SET workspace = CASE
WHEN 'value1' = ANY(workspaces) THEN 'value1'
WHEN 'value2' = ANY(workspaces) THEN 'value2'
ELSE 'default_value'
END
""")
# Remove the old column
alter table(:projects) do
remove(:workspaces)
end