为什么在新服务器上出现“PG::UndefineFunction: ERROR: function gen_random_uuid() does not Exist”而在旧服务器上却没有?

Mat*_*hew 2 postgresql ubuntu ruby-on-rails heroku pgcrypto

我有一个可以在本地运行的现有 Rails 7 / PostgreSQL 应用程序,并且当前部署在 Heroku 上。我正在将其迁移到运行 Ubuntu 22 LTS(最初是 Ubuntu 20 LTS)的 VPS,但是当我尝试运行迁移(直接或通过 Capistrano)时,它们失败并出现错误:

PG::UndefinedFunction:错误:函数 gen_random_uuid() 不存在

第一个(十个!)迁移失败了,因此,我没有重写历史记录并插入/修改早期迁移,而是通过手动创建扩展在服务器上修复了它pgcrypto

            myApp$  sudo su - postgres
         postgres$  psql
        postgres=#  \c myapp_production
myapp_production=#  CREATE EXTENSION pgcrypto;
                    CREATE EXTENSION
myapp_production=#  exit
Run Code Online (Sandbox Code Playgroud)

据我所知,我没有执行任何操作来在 Mac 上启用该扩展,我只是在第一次迁移中运行rails new myapp --database=postgresql并使用了该扩展。create_table :people, id: :uuid do |t|

为什么我需要在 Ubuntu 上创建/启用此扩展,而不是 macOS 或 Heroku?

在我的 Mac 上,我使用 Postgres 14.5(psql (PostgreSQL) 14.5,Homebrew)。在 Ubuntu 22 LTS 服务器上,我还使用 Postgres 14.5(psql (PostgreSQL) 14.5、Ubuntu 14.5-0ubuntu0.22.04.1)。

当我第一次注意到它时,我在服务器上使用了不同版本的 PostgreSQL(psql (PostgreSQL) 12.12、Ubuntu 12.12-0ubuntu0.20.04.1)。

根据Heroku Postgres Web 仪表板,我在 Heroku 上使用 Postgres 13.9。

更奇怪的是,当我检查开发和生产中该数据库的已安装扩展时,pgcrypto 甚至没有列出:

# macOS using psql
myapp_development=# \dx
                 List of installed extensions
  Name   | Version |   Schema   |         Description          
---------+---------+------------+------------------------------
 plpgsql | 1.0     | pg_catalog | PL/pgSQL procedural language
(1 row)

# Heroku using `heroku pg:psql`
myapp::DATABASE=> \dx
                 List of installed extensions
  Name   | Version |   Schema   |         Description          
---------+---------+------------+------------------------------
 plpgsql | 1.0     | pg_catalog | PL/pgSQL procedural language
(1 row)
Run Code Online (Sandbox Code Playgroud)

:uuid我的专栏在这两个平台上运行得怎么样!?

Erw*_*ter 5

毕竟解释很简单:
gen_random_uuid()被添加到 Postgres 13 的主发行版中。(使用 检查 Postgres 版本SELECT version();

这与服务器的操作系统无关。这也与交互式终端psql
的版本无关(可能与服务器版本不同)。

Postgres 13 的发行说明

添加gen_random_uuid()生成版本 4 UUID 的功能 (Peter Eisentraut)

以前 UUID 生成功能仅在外部模块uuid-ossppgcrypto中可用。