У меня есть существующее приложение Rails 7/PostgreSQL, которое я могу запускать локально, и в настоящее время оно развернуто на Heroku. Я переношу его на VPS под управлением Ubuntu 22 LTS (первоначально Ubuntu 20 LTS), но когда я попытался запустить миграцию (напрямую или через 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
Насколько я помню, я ничего не делал, чтобы включить расширение на своем 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 я использую Postgres 13.9 на Heroku.
Еще более странно, когда я проверяю установленные расширения для этой базы данных как в разработке, так и в рабочей среде, 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)
Как мои :uuid
колонки работают на этих двух платформах!?
Объяснение в конце концов простое:
gen_random_uuid() был добавлен в основной дистрибутив с Postgres 13. (Проверьте версию Postgres с SELECT version();
)
Это не связано с ОС сервера.
Это также не связано с версией интерактивного терминала psql (которая может отличаться от версии сервера).
Примечания к выпуску Postgres 13:
Добавьте функцию gen_random_uuid() для генерации UUID версии 4. (Питер Эйзентраут)
Ранее функции генерации UUID были доступны только в внешние модули uuid-ossp и pgcrypto.
Спасибо! Очень полезно знать, что psql --version
может вводить в заблуждение! Я обновился с 12 до 14 (слегка изменив эти инструкции paulox.net/2022/04/28/…), и когда я воссоздал базу данных без расширения, мои миграции прошли правильно.
Обратите внимание, что версия
psql
на самом деле не говорит вам о версии сервера.