【问题标题】:PostgreSQL pgp_sym_encrypt() broken in version 9.1PostgreSQL pgp_sym_encrypt() 在 9.1 版中被破坏
【发布时间】:2011-12-28 23:35:51
【问题描述】:

以下在 PostgreSQL 8.4 中有效:

insert into credentials values('demo', pgp_sym_encrypt('password', 'longpassword'));

当我在 9.1 版中尝试时,我得到了这个:

错误:函数 pgp_sym_encrypt(unknown, unknown) 不存在 LINE 1: 插入凭证值('demo', pgp_sym_encrypt('pass... ^ 提示:没有函数匹配给定的名称和参数类型。您可能需要添加 显式类型转换。

***错误***

错误:函数 pgp_sym_encrypt(unknown, unknown) 不存在 SQL 状态:42883 提示:没有函数匹配给定的名称和参数 类型。您可能需要添加显式类型转换。字符:40

如果我尝试一些像这样的显式转换

insert into credentials values('demo', pgp_sym_encrypt(cast('password' as text), cast('longpassword' as text)))

我收到一条略有不同的错误消息:

错误:函数 pgp_sym_encrypt(text, text) 不存在

我已经安装了 pgcrypto。有人在 PostgreSQL 9.1 中使用 pgp_sym_encrypt() 吗?

【问题讨论】:

    标签: postgresql pgp postgresql-9.1


    【解决方案1】:

    解释可能是模块安装到了不在您的搜索路径中的架构中 - 或者安装到了错误的数据库中。
    使用此查询诊断您的问题并报告输出:

    SELECT n.nspname, p.proname, pg_catalog.pg_get_function_arguments(p.oid) as params
    FROM   pg_catalog.pg_proc p
    JOIN   pg_catalog.pg_namespace n ON n.oid = p.pronamespace
    WHERE  p.proname ~~* '%pgp_sym_encrypt%'
    AND    pg_catalog.pg_function_is_visible(p.oid);
    

    在数据库的所有模式中查找函数。类似于 psql 元命令

    \df *pgp_sym_encrypt*
    

    【讨论】:

    • 即使 pgcrypto 安装在 postgres 数据库中,您的 select 语句也不会返回任何内容。我尝试将 pgcrypto 安装在不同的数据库中,但它失败并出现错误提示它已安装。我已经从 postgres db 中删除了 pgcrypto,但是当我运行以下命令时它仍然失败,因为它认为它已安装: psql -d VGDB -U postgres -c "create extension pgcrypto" 我用 Python 运行这个命令,但我没有不知道为什么这很重要。
    • @DeanSchulze 大多数 PostgreSQL 扩展都必须每个数据库安装。在postgres 数据库中安装pgcrypto 肯定不是您想要的。将它安装在您要使用它的同一个数据库中。如果我的查询(在同一个数据库中执行!)没有找到任何东西,则扩展程序安装不正确。在继续之前,您需要了解database clusterdatabaseschema 的概念。您可以先在 excellent manual 中搜索这些术语。
    【解决方案2】:

    确保在所需架构上安装扩展。

    sudo -i -u postgres
    psql $database
    CREATE EXTENSION pgcrypto;
    

    【讨论】:

      【解决方案3】:

      好的,问题解决了。

      我正在创建 pgcrypto 扩展作为脚本中的第一个操作。然后我删除并添加了 VGDB 数据库。这就是为什么 pgcrypto 在创建后立即存在,但在稍后在脚本中运行 sql 或打开 pgadmin 时不存在。

      此脚本用于设置新数据库,如果我在新数据库上尝试过,创建扩展程序将立即失败。

      我的错。谢谢你的帮助,欧文。

      【讨论】:

        【解决方案4】:

        只需提及安装 pgcrypto 的 de 架构,如下所示:

        @ColumnTransformer(forColumn = "TEST",
                read =  "public.pgp_sym_decrypt(TEST, 'password')",
                write = "public.pgp_sym_encrypt(?, 'password')")
        @Column(name = "TEST", columnDefinition = "bytea", nullable = false)
        private String test;
        

        【讨论】:

          【解决方案5】:

          我再次运行我的 (python) 脚本并且 CREATE EXTENSION 运行没有错误。该脚本也执行此命令

          psql -d VGDB -U postgres -c "select * from pg_available_extensions order by name"
          

          结果集中包含以下内容:

          pgcrypto           | 1.0             | 1.0               | cryptographic functions
          

          所以psql认为它已经安装了pgcrypto。

          稍后在我执行时在同一个脚本中

          psql -d VGDB -U postgres -f sql/Create.Credentials.table.sql
          

          其中 sql/Create.Credentials.table.sql 包含此内容

          insert into credentials values('demo', pgp_sym_encrypt('password', 'longpassword'));
          

          我明白了

          psql:sql/Create.Credentials.table.sql:31: ERROR:  function pgp_sym_encrypt(unknown, unknown) does not exist
          LINE 1: insert into credentials values('demo', pgp_sym_encrypt('pass...
                                                         ^
          HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
          

          当我打开 pgadmin 时,它不会在 VGDB 或 postgres 数据库中显示 pgcrypto,即使上面由 psql 调用的查询显示已安装 pgcrypto。

          使用 psql 执行“create extension ...”命令后是否需要提交?我的其他 DDL 或 SQL 语句在使用 psql 执行时都不需要提交。

          开始看起来 psql 只是 flakey。是否有另一种方法来调用“创建扩展 pgcrypto” - 例如使用 Python 的数据库支持类 - 还是必须通过 psql 运行?

          【讨论】:

            猜你喜欢
            • 2018-11-21
            • 2020-02-15
            • 2023-04-02
            • 1970-01-01
            • 1970-01-01
            • 2023-03-15
            • 1970-01-01
            • 2014-01-06
            • 1970-01-01
            相关资源
            最近更新 更多