我有一个project,它调用Postgres函数gen_random_bytes
,declared就像这样:
CREATE OR REPLACE FUNCTION core.gen_random_bytes(integer) RETURNS bytea AS '$libdir/pgcrypto', 'pg_random_bytes' LANGUAGE c STRICT;
只要我在本地机器上使用它,它工作正常。但是我无法在Heroku上创建该功能 - 我收到以下错误:
[WARNING ] CREATE OR REPLACE FUNCTION core.gen_random_bytes(integer) RETURNS bytea AS '$libdir/pgcrypto', 'pg_random_bytes' LANGUAGE c STRICT
ERROR: permission denied for language c
似乎只有超级用户才能在C中声明函数。我找到了另一个answer,建议使用命令
UPDATE pg_language SET lanpltrusted = true WHERE lanname LIKE 'c';
我没有获得该命令的许可:
ERROR: permission denied for relation pg_language
SQL state: 42501
如何让我的代码在Heroku上运行?
我至少有以下选项:
core.gen_random_bytes
。core.gen_random_bytes
的一些现有替代方案,但这并不需要超级用户。现在,我只是为这个项目做原型设计。哪个选项最简单(包括我没有提到的内容)?
答案 0 :(得分:5)
答案是:你不能除非你自己在一个裸实例上运行Postgres(我不确定它是Heroku上的一个选项)。
所有Postgres托管服务(如Heroku和Amazon RDS)的缺点是内部需要能够在单个虚拟服务器中运行多个Postgres数据库。这意味着他们不能允许Postgres做任何可能影响操作系统级别事情的事情。不受信任的过程语言(例如C,plpythonu和plperlu,但不是plperl)能够在运行Postgres的OS用户可以在操作系统级别执行任何操作。这是一个在共享环境中无法接受的安全漏洞。 (举个例子,在服务器上为每个其他客户阅读原始的Postgres数据很容易。)
这里唯一的选择是自己安装和管理Postgres。在亚马逊上这很容易;只需使用您选择的操作系统获取原始EC2实例并在其上拍击Postgres。你失去了RDS为你提供的一些易维护性,但是如果你知道Postgres它真的没什么大不了的。我倾向于推动我的客户做到这一点,这样我就能够使用RDS团队没有祝福的扩展(在共享环境中不安全的其他东西)。
我对Heroku的产品并不熟悉,但只要它们具有与裸EC2实例相当的东西,你就可以做同样的事情。