Ecto - 将 table 列迁移到它自己的连接 table 中(将数据转移到新的 tables)
Ecto - migrate table column into its own join table (shifting the DATA to the new tables)
我想从这里开始:
schema "products" do
field :name, :string
field :brand, :string
...more fields...
end
为此:
schema "products" do
field :name, :string
...more fields...
end
schema "brands" do
field :name, :string
...more fields...
end
schema "product_brand_joins" do
field :p_id, :integer
field :b_id, :integer
...more fields...
end
不会丢失我当前的数据,其中包含带有字符串 :brand 字段的产品。
我了解如何创建新品牌 table 和 product_brand_joins table 并通过外迁移从产品 table 中删除“:brand”。但是有没有办法将我当前的数据操纵到新的 table 中?
您可以使用 execute/1
或 execute/2
函数执行 SQL 语句,接受两个参数的那个是第一个参数的可回滚版本,它期望执行语句迁移时执行,回滚时执行。
因此,您可以使用它来定义迁移时应该发生的事情,这变成了定义语句的问题。 this docs page from PostgreSQL末尾有一个基于子查询插入的例子,我们将在这里使用。
在您的迁移 .exs
文件中:
use Ecto.Migration
def up do
create table(:brands) do
add :name, :string,
# add other fields
end
create table("product_brand_joins") do
add :product_id, references: :products
add :brand_id, references: :brands
end
# Insert into the brands table a brand with each name found in products
execute(
"INSERT INTO brands(name)
SELECT DISTINCT(brand) FROM products"
)
# Insert into the joined table the product and brand ids
execute(
"INSERT INTO product_brand_joins(product_id, brand_id)
SELECT p.id, b.id FROM products p LEFT JOIN brands b ON p.brand = b.name"
)
# And finally delete the column from products
alter table(:products) do
remove :brand
end
end
然后对于回滚,您将在迁移中实现 down
函数以使用类似的逻辑恢复过程:在 products
中创建品牌列,并用相应的名称填充它品牌取决于产品 ID,并删除新表。
我想从这里开始:
schema "products" do
field :name, :string
field :brand, :string
...more fields...
end
为此:
schema "products" do
field :name, :string
...more fields...
end
schema "brands" do
field :name, :string
...more fields...
end
schema "product_brand_joins" do
field :p_id, :integer
field :b_id, :integer
...more fields...
end
不会丢失我当前的数据,其中包含带有字符串 :brand 字段的产品。
我了解如何创建新品牌 table 和 product_brand_joins table 并通过外迁移从产品 table 中删除“:brand”。但是有没有办法将我当前的数据操纵到新的 table 中?
您可以使用 execute/1
或 execute/2
函数执行 SQL 语句,接受两个参数的那个是第一个参数的可回滚版本,它期望执行语句迁移时执行,回滚时执行。
因此,您可以使用它来定义迁移时应该发生的事情,这变成了定义语句的问题。 this docs page from PostgreSQL末尾有一个基于子查询插入的例子,我们将在这里使用。
在您的迁移 .exs
文件中:
use Ecto.Migration
def up do
create table(:brands) do
add :name, :string,
# add other fields
end
create table("product_brand_joins") do
add :product_id, references: :products
add :brand_id, references: :brands
end
# Insert into the brands table a brand with each name found in products
execute(
"INSERT INTO brands(name)
SELECT DISTINCT(brand) FROM products"
)
# Insert into the joined table the product and brand ids
execute(
"INSERT INTO product_brand_joins(product_id, brand_id)
SELECT p.id, b.id FROM products p LEFT JOIN brands b ON p.brand = b.name"
)
# And finally delete the column from products
alter table(:products) do
remove :brand
end
end
然后对于回滚,您将在迁移中实现 down
函数以使用类似的逻辑恢复过程:在 products
中创建品牌列,并用相应的名称填充它品牌取决于产品 ID,并删除新表。