Geo*_*iev 3 postgresql ruby-on-rails rails-migrations postgresql-9.3 ruby-on-rails-5
在我的 Rails 5.0.5 应用程序中,我需要将json列转换为string, array: true.
我的列中的值json如下:
[ "200px-RR5219-0015R.png", "2017_03_25_2235.doc", "137555.jpg" ]
Run Code Online (Sandbox Code Playgroud)
我尝试过这个迁移:
[ "200px-RR5219-0015R.png", "2017_03_25_2235.doc", "137555.jpg" ]
Run Code Online (Sandbox Code Playgroud)
并得到这个错误:
ActiveRecord::StatementInvalid: PG::DatatypeMismatch: ERROR: column "attachments" cannot be cast automatically to type character varying[]
HINT: You might need to specify "USING attachments::character varying[]".
: ALTER TABLE "tasks" ALTER COLUMN "attachments" TYPE character varying[]
Run Code Online (Sandbox Code Playgroud)
然后我编辑了迁移:
class ChangeTaskAttachmentsTypeToString < ActiveRecord::Migration[5.0]
def change
change_column :tasks, :attachments, :string, array: true
end
end
Run Code Online (Sandbox Code Playgroud)
最后得到这个错误:
PG::CannotCoerce: ERROR: cannot cast type json to character varying[]
: ALTER TABLE "tasks" ALTER COLUMN "attachments" TYPE character varying[] USING attachments::character varying[]
Run Code Online (Sandbox Code Playgroud)
我该如何进行此迁移?
我猜数组元素是文件名。如果是这样,那么您可以删除所有字符[]"和空格并将结果拆分为数组,如下所示:
with my_table(attachments) as (
values
('[ "200px-RR5219-0015R.png", "2017_03_25_2235.doc", "137555.jpg" ]'::json)
)
select string_to_array(translate(attachments::text, '[] "', ''), ',')::varchar[]
from my_table;
string_to_array
---------------------------------------------------------
{200px-RR5219-0015R.png,2017_03_25_2235.doc,137555.jpg}
(1 row)
Run Code Online (Sandbox Code Playgroud)
所以使用:
... USING string_to_array(translate(attachments::text, '[] "', ''), ',')::varchar[]
Run Code Online (Sandbox Code Playgroud)
更正式(和通用)的解决方案需要自定义函数,例如:
with my_table(attachments) as (
values
('[ "200px-RR5219-0015R.png", "2017_03_25_2235.doc", "137555.jpg" ]'::json)
)
select string_to_array(translate(attachments::text, '[] "', ''), ',')::varchar[]
from my_table;
string_to_array
---------------------------------------------------------
{200px-RR5219-0015R.png,2017_03_25_2235.doc,137555.jpg}
(1 row)
Run Code Online (Sandbox Code Playgroud)
可以用在
... USING string_to_array(translate(attachments::text, '[] "', ''), ',')::varchar[]
Run Code Online (Sandbox Code Playgroud)
请注意,我使用text[]Postgres 作为更自然的选择,但varchar[]如果重要的话您可以将其替换为。
在 Db<>fiddle 中测试它。
| 归档时间: |
|
| 查看次数: |
6859 次 |
| 最近记录: |