[英]Rails & PSQL: how to convert a column of type STRING to UUID with a fallback value
我正在使用名为'pgcrypto'的扩展来添加对UUID的支持。
目前我有一个名为creator_id
的列类型为string,但我想将其类型更改为UUID。
起初我尝试过:
change_column :communities, :creator_id, :uuid
我得到了这个:
PG::DatatypeMismatch: ERROR: column "creator_id" cannot be cast automatically to type uuid
HINT: You might need to specify "USING creator_id::uuid".
所以我尝试过:
change_column :communities, :creator_id, "uuid USING creator_id::uuid"
问题是,在开发的早期阶段,它充满了占位符值甚至看起来不像UUID,所以我收到以下错误:
PG::InvalidTextRepresentation: ERROR: invalid input syntax for type uuid
所以我想在引发这样的异常时回退到某个默认的UUID。 我如何实现这一目标?
首先,使用uuid-ossp
和pgcrypto
创建迁移
class EnableUuidExtension < ActiveRecord::Migration[5.2]
def change
enable_extension 'uuid-ossp'
enable_extension 'pgcrypto'
end
end
然后,创建另一个迁移以将id
转换为uuid
。 例如,
class ChangeIdToUuidInUser < ActiveRecord::Migration[5.2]
def change
add_column :users, :uuid, :uuid, default: 'uuid_generate_v4()', null: false
change_table :users do |t|
t.remove :id
t.rename :uuid, :id
end
execute 'ALTER TABLE users ADD PRIMARY KEY (id);'
end
end
然后使用此命令打开postgres数据库psql -U username databaseName
您将在postgres shell中输入,运行以下命令
=# CREATE EXTENSION pgcrypto;
=# \q
最后,运行rails db:migrate
这就是我最终做的事情:
class UpdateCreatorIdInCommunities < ActiveRecord::Migration[5.1]
def up
execute "CREATE OR REPLACE FUNCTION string_to_uuid(text, uuid) RETURNS uuid AS $$
BEGIN
RETURN $1::uuid;
EXCEPTION
WHEN invalid_text_representation THEN
RETURN $2;
END;
$$ language plpgsql immutable;"
last_user_created = User.order(:created_at).last
user_id = last_user_created ? quote(last_user_created.id) : "NULL"
change_column :communities, :creator_id, "uuid USING string_to_uuid(\"creator_id\", #{user_id})"
end
def down
change_column :communities, :creator_id, :string
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.