Postgres 提取多态列
Postgres extracting a polymorphic column
我有以下 table 称为 feeds
:
from_type | from_id
-----------+---------
user | 1
project | 1
user | 2
program | 1
program | 2
project | 1
challenge | 1
project | 3
community | 1
我想将其转换为:
from_type | user_id | project_id | program_id | challenge_id | community_id
-----------+---------+------------+------------+--------------+-------------
user | 1 | | | |
project | | 1 | | |
user | 2 | | | |
program | | | 1 | |
program | | | 2 | |
project | | 1 | | |
challenge | | | | 1 |
project | | 3 | | |
community | | | | | 1
我这样做的原因是,如果我们需要回滚,可以进行反向迁移。我设法用 coalesce + update statement
将底部版本转换为顶部版本,但我不太确定如何执行反向操作。
这是向上迁移,向下迁移应该是什么样的?
class PolymorphicFeedTable < ActiveRecord::Migration[5.2]
def up
execute <<-SQL
UPDATE feeds SET
from_id = coalesce(user_id, project_id, community_id, challenge_id, program_id, need_id);
SQL
end
def down
execute <<-SQL
?
SQL
end
end
如果展开 up
方法:
def up
%w[challenge community need program project user].each do |type|
execute("update feeds set from_id = #{type}_id where from_type = '#{type}'")
end
end
然后就可以看到回去的路了,把赋值倒过来就好了:
def down
%w[challenge community need program project user].each do |type|
execute("update feeds set #{type}_id = from_id where from_type = '#{type}'")
# ------------------------^^^^^^^^^^^^^^^^^^^^
end
end
假设您的 table 数据没有损坏(即您的 from_type
值与 X_id
列匹配)。
您可以 connection.quote(type)
而不是简单地手动将 #{type}
括在单引号中,但您知道这些类型事先是安全的,因此没有必要这样做。 connection.quote_column_name
和 #{type}_id
插值也是如此。
我有以下 table 称为 feeds
:
from_type | from_id
-----------+---------
user | 1
project | 1
user | 2
program | 1
program | 2
project | 1
challenge | 1
project | 3
community | 1
我想将其转换为:
from_type | user_id | project_id | program_id | challenge_id | community_id
-----------+---------+------------+------------+--------------+-------------
user | 1 | | | |
project | | 1 | | |
user | 2 | | | |
program | | | 1 | |
program | | | 2 | |
project | | 1 | | |
challenge | | | | 1 |
project | | 3 | | |
community | | | | | 1
我这样做的原因是,如果我们需要回滚,可以进行反向迁移。我设法用 coalesce + update statement
将底部版本转换为顶部版本,但我不太确定如何执行反向操作。
这是向上迁移,向下迁移应该是什么样的?
class PolymorphicFeedTable < ActiveRecord::Migration[5.2]
def up
execute <<-SQL
UPDATE feeds SET
from_id = coalesce(user_id, project_id, community_id, challenge_id, program_id, need_id);
SQL
end
def down
execute <<-SQL
?
SQL
end
end
如果展开 up
方法:
def up
%w[challenge community need program project user].each do |type|
execute("update feeds set from_id = #{type}_id where from_type = '#{type}'")
end
end
然后就可以看到回去的路了,把赋值倒过来就好了:
def down
%w[challenge community need program project user].each do |type|
execute("update feeds set #{type}_id = from_id where from_type = '#{type}'")
# ------------------------^^^^^^^^^^^^^^^^^^^^
end
end
假设您的 table 数据没有损坏(即您的 from_type
值与 X_id
列匹配)。
您可以 connection.quote(type)
而不是简单地手动将 #{type}
括在单引号中,但您知道这些类型事先是安全的,因此没有必要这样做。 connection.quote_column_name
和 #{type}_id
插值也是如此。