【发布时间】:2016-12-19 00:08:47
【问题描述】:
我创建了两个 postgres 数据库。版本 9.5.4。第一个数据库叫做persist。我正在使用来自postgrest 的一些示例代码进行身份验证。代码效果很好,这是我的持久数据库定义:
create schema localschema;
grant all on schema localschema to postgres;
create table localschema.users (
email text primary key check ( email ~* '^.+@.+\..+$' ),
pass text not null check (length(pass) < 512),
role name not null check (length(role) < 512),
verified boolean not null default false
-- If you like add more columns, or a json column
);
create or replace function
localschema.encrypt_pass() returns trigger
language plpgsql
as $$
declare
mvar text;
begin
if tg_op = 'INSERT' or new.pass <> old.pass then
new.pass = crypt(new.pass, gen_salt('bf'::text));
end if;
return new;
end
$$;
drop trigger if exists encrypt_pass on localschema.users;
create trigger encrypt_pass
before insert or update on localschema.users
for each row
execute procedure localschema.encrypt_pass();
相当简单,这里我调用了对表的插入,然后是一个选择,你可以看到通过触发器/函数 encrypt_pass 加密的 pass 使用:
persist=# insert into localschema.users values('g@l.com','123123','postgres');
persist=# select * from localschema.users;
email | pass | role | verified
---------+--------------------------------------------------------------+----------+----------
g@l.com | $2a$06$5p5eM6sJAfxZ4qSv0Jgx..GlflYkNeE7aY.D4kR9K0glRZv2wU7ue | postgres | f
(1 row)
效果很好。下一步是postgres_fdw,我将外部模式导入到远程数据库到我的另一个数据库:
CREATE EXTENSION IF NOT EXISTS "postgres_fdw";
create server self foreign data wrapper postgres_fdw options(host '127.0.0.1', dbname 'persist', port '5432');
create user mapping for postgres server self options (user 'postgres');
create schema "localschema";
grant all on schema localschema to postgres;
import foreign schema localschema from server self into "localschema" options ( import_default 'true');
然后一个选择来证明它是有效的:
cache=# select * from localschema.users;
email | pass | role | verified
---------+--------------------------------------------------------------+----------+----------
g@l.com | $2a$06$5p5eM6sJAfxZ4qSv0Jgx..GlflYkNeE7aY.D4kR9K0glRZv2wU7ue | postgres | f
(1 row)
问题是我不能插入到这个表中。以下是实际操作中的错误:
cache=# insert into localschema.users values ('f@l.com','234234','postgres');
ERROR: function gen_salt(text) does not exist
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
CONTEXT: Remote SQL command: INSERT INTO localschema.users(email, pass, role, verified) VALUES ($1, $2, $3, $4)
PL/pgSQL function localschema.encrypt_pass() line 6 at assignment
很奇怪,找不到任何函数,不只是gen_salt。我在持久化端放置了一些引发异常语句,以验证我的 current_user 确实是 postgres。那么,为什么我通过 postgres_fdw 执行时我的所有函数都会消失?
我错过了什么?我很确定我已经完成了这项工作,但是在我的所有设置/拆卸过程中,我不知何故失去了正确的咒语。
【问题讨论】:
-
请不要混淆答案和问题。答案应该在下面的 Answers 部分下。我继续从问题中删除答案并将其发布为 CW。随意发布答案并联系我,以便我删除 CW