Rails + Postgres迁移 - 为什么我会收到错误信息"PG::UndefinedFunction: ERROR: function gen_random_uuid() does not exist"?

23
我其中一份Rails迁移使用uuid作为主键。Postgres扩展gen_random_uuid()应该解决此问题,但是在安装相关扩展(uuid-ossp)后,我仍然遇到错误。
4个回答

48
问题在于每次我执行重置和迁移(例如rake db:drop db:create db:migrate)时,uuid-ossp扩展都会被删除。

解决方法是创建一个先于所有其他迁移运行的迁移,以启用相关的扩展。就像这样(db/migrate/0_enable_extensions.rb):

class EnableExtensions < ActiveRecord::Migration[5.1]
  def change
    enable_extension 'uuid-ossp'
    enable_extension 'pgcrypto'
  end
end

将迁移的名称更改为0_XXX就解决了问题 :) - Cris R

2

我在使用uuid作为主键生成模型后也遇到了同样的错误:

rails g scaffold user name --primary-key-type=uuid

我忘记在迁移文件中加载pgcrypto扩展

解决方案:

只需添加以下内容即可:

enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto')

将迁移文件修改如下:

class CreateUsers < ActiveRecord::Migration[7.0]
  enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto') # <-- HERE
  def change
    create_table :users, id: :uuid do |t|
      t.string :name
      t.timestamps
    end
  end
end

然后运行rake db:migrate就能成功了。

这需要数据库用户根据config/database.yml中的“用户名”具有超级用户角色。为此,请以postgres用户身份运行ALTER ROLE username SUPERUSER。如果您不想将此角色分配给db用户,请作为postgresql登录,连接到相关的db并运行CREATE EXTENSION pgcrypto; - Andreas Gebhard

0

边缘情况的解答:

按照上述说明添加启用扩展的迁移。

如果您之前使用的是bigint id,并且要转换为UUID,则运行rake db:reset db:migrate会失败。请务必按照上述说明运行rake db:drop db:create db:migrate

如果出现错误Environment data not found in the schema,请运行bin/rails db:environment:set RAILS_ENV=development


0

这个错误对我来说打击很大,尽管我已经安装了uuid-ossppgcrypto扩展。经过多次尝试,我终于找到了解决方法。

对我来说,问题出在存在多个数据库,并且在非默认数据库中有一些迁移尚未完成。为了解决这个问题,我只需运行以下命令:

RAILS_ENV=development rails db:drop:all
RAILS_ENV=development rails db:create:all
RAILS_ENV=development rails db:migrate:all

测试环境同样适用。

RAILS_ENV=test rails db:drop:all
RAILS_ENV=test rails db:create:all
RAILS_ENV=test rails db:migrate:all

希望这对于正在处理多个数据库的人有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接