扩展存在,但uuid_generate_v4失败

206

在Amazon EC2 RDS上使用PostgreSQL:

=> SHOW rds.extensions;

rds.extensions                                                                                                                                 
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 btree_gin,btree_gist,chkpass,citext,cube,dblink,dict_int,dict_xsyn,earthdistance,fuzzystrmatch,hstore,intagg,intarray,isn,ltree,pgcrypto,pgrowlocks,pg_trgm,plperl,plpgsql,pltcl,postgis,postgis_tiger_geocoder,postgis_topology,sslinfo,tablefunc,tsearch2,unaccent,uuid-ossp
(1 row)

正如您所看到的,uuid-ossp扩展确实存在。 但是,当我调用生成uuid_v4函数时,会失败:

CREATE TABLE my_table (
    id uuid DEFAULT uuid_generate_v4() NOT NULL,
    name character varying(32) NOT NULL,

);

这个有什么问题吗?


11
将来请始终显示任何错误信息的确切文本 - Craig Ringer
3
是的,扩展存在,但数据库可能处于不一致状态。可能发生这种情况的原因之一是如果您删除模式但保留扩展名。为避免这种情况,最好运行 DROP EXTENSION IF EXISTS "uuid-ossp" CASCADE; 然后 CREATE EXTENSION "uuid-ossp"; (请参见@atomCode下面的答案中的详细说明) - Athanassios
13个回答

452

这个扩展程序是可用的,但是并没有在这个数据库中安装

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

22
命令应为CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; - boatcoder
15
为了明确起见,在 pgsql 控制台中选择数据库,可以编写 \c <数据库名称> - ElementalStorm
@CraigRinger 我在哪里可以找到这个文档? - Abhishek Mani
1
在 pgsql 控制台中运行 \c <dbname> 时,我遇到了身份验证错误。我使用 Ubuntu 命令行成功地解决了这个问题。sudo -u postgres psql <db_name>。之后,我按照指示运行了 CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; - Joachim Rives
我收到了错误信息:“ERROR: 无法打开扩展控制文件“/usr/share/pgsql/extension/uuid-ossp.control”:没有这样的文件或目录”。 - eggsloveoats

44

如果扩展已经存在,但是当您执行描述函数\df命令时没有看到uuid_generate_v4()函数,则您只需要删除扩展并重新添加它,以便这些函数也被添加。以下是问题复制:

db=# \df
                       List of functions
 Schema | Name | Result data type | Argument data types | Type
--------+------+------------------+---------------------+------
(0 rows)
CREATE EXTENSION "uuid-ossp";
ERROR:  extension "uuid-ossp" already exists
DROP EXTENSION "uuid-ossp";
CREATE EXTENSION "uuid-ossp";
db=# \df
                                  List of functions
 Schema |        Name        | Result data type |    Argument data types    |  Type
--------+--------------------+------------------+---------------------------+--------
 public | uuid_generate_v1   | uuid             |                           | normal
 public | uuid_generate_v1mc | uuid             |                           | normal
 public | uuid_generate_v3   | uuid             | namespace uuid, name text | normal
 public | uuid_generate_v4   | uuid             |                           | normal

db=# select uuid_generate_v4();
           uuid_generate_v4
--------------------------------------
 b19d597c-8f54-41ba-ba73-02299c1adf92
(1 row)

可能发生的情况是该扩展程序在过去某个时间点添加到集群中,然后您可能在此之后创建了一个新的数据库。如果是这种情况,则新数据库将只“知道”该扩展程序,但它不会添加 uuid 函数,这仅会在您添加该扩展程序时发生。因此,您必须重新添加该扩展程序。


是的,我也遇到了那个问题,你在这里描述的方法解决了它。 - Athanassios

27

看起来该扩展程序未在您需要的特定数据库中安装。

您应该使用以下方式连接到此特定数据库:

 \CONNECT my_database

然后在这个数据库中安装扩展

 CREATE EXTENSION "uuid-ossp";

请执行以下命令:psql <your_dbName>,然后粘贴此代码:CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; - Akintunde Israel

23

步骤#1:将uuid-ossp扩展重新安装到准确的模式中:

如果这是一个全新的安装,您可以跳过SETDROP。 感谢@atomCode (详情)

SET search_path TO public;
DROP EXTENSION IF EXISTS "uuid-ossp";

CREATE EXTENSION "uuid-ossp" SCHEMA public;

之后,在psql命令行提示符中执行\df查询,你应该在正确的模式下看到uuid_generate_v4()函数。

步骤#2:使用完全限定的名称(带有schemaname.限定符):

例如:

CREATE TABLE public.my_table (
    id uuid DEFAULT public.uuid_generate_v4() NOT NULL,

1
谢谢。我首先通过删除并创建带有模式的扩展来创建,但它没有起作用,接下来我转到默认设置并编写了schema.uuid_generate_v4(),这样就解决了问题。 - Danish

10
如果您已更改了 search_path ,请在函数调用中指定 public 模式:
public.uuid_generate_v4()

7
这对我有用。
create extension IF NOT EXISTS "uuid-ossp" schema pg_catalog version "1.1"; 

确保扩展名应该在pg_catalog而不是你的模式中...


6
只需将以下代码添加到您脚本的开头即可。
DROP EXTENSION IF EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

1
也许我遇到了相同的问题。 uuid_generate_v4 来自于 public 模式,而我正在尝试在特定模式下运行它,所以为了解决这个问题,我做了以下操作:
SET search_path TO specific_schema;

INSERTO INTO my_table VALUES public.uuid_generate_v4();

您可以检查函数运行的模式:

\df uuid_generate_v4

或者

SELECT n.nspname, p.probin, p.proname
FROM
    pg_proc p
    LEFT JOIN pg_namespace n ON p.pronamespace = n.oid
WHERE p.proname like 'uuid_generate_v4';

你可以通过以下方式查看与uuid-ossp扩展相关的信息:
SELECT * FROM pg_extension WHERE extname LIKE 'uuid-ossp';

如果您还没有此扩展程序,您可以添加它:

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

0
在我的情况下,有三个步骤。创建数据库,连接到数据库并创建扩展。重要的步骤是第二步,“连接到数据库”,您可以注意到该行没有“;”因为它是一个命令而不是SQL语句。
CREATE DATABASE database_name_here;
\connect database_name_here 
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

0

如果您使用Unix命令(除了PGAdmin)执行此操作,请不要忘记将DB作为参数传递。否则,在执行此DB上的请求时,此扩展将无法启用。

psql -d -c "create EXTENSION pgcrypto;"


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