PG数据库,跨schema访问,并且不带schema前缀
最近在搭建环境的时候遇到这样的问题,tpl_user_t的表在 schema SD 下面,而 我的数据源的账号是EI, 也就是说要在schema EI下访问schema SD下的表, 在连接数据库的时候,报错 tpl_user_t 不存在,因为查询的 SQL 是框架内部的,无法更改,也就是说必须 通过 select * from tpl_user_t 查询,而不是 select * from SD.tpl_user_t 查询。当时想到了下面几个方法。
(1)通过schema授权的当时
- 将SCHEMA的权限授权给用户:
grant all on SCHEMA SD to EI; - 此时用户还没有读写权限,需要继续授权表 :
GRANT SELECT ON TABLE SD.tpl_user_t TO EI;
但是依然无法通过不带schema 来查询tpl_user_t;
(2)查询 资料发现PG 在查询的时候,用到了search_path
- search_path类似于linux中的path环境变量。默认值是$user,public,意思就是当以某个用户登录到数据库的时候,默认就是先查找和登录用户同名的schema,再查找public。
- 先用SHOW search_path ;(或者: select name, setting from pg_settings where name = 'search_path';) 查询结果确实没有SD, 于是给他加上这个schema : set search_path = "$user", EI, public,SD;
- 在之后查询的时候发现,现在可以在EI的用户下不带schema查询 tpl_user_t了, 但是当我断开重连数据库后,又是同样的情况, 查资料发现这个命令只是-- To change search_path on a connection-level **(连接级别的,连接断开后不生效)**
- 最后使用 命令:
alter role EI set search_path to "$user", EI, SD,public;
断开重连后依然生效;
总结:
- PG查询的过程中通过show search_path 可以查询哪些表所在的schema在查询是不用带schema。
- 如果两个schema A, B,并且A,B中都有c表的情况下,在用户以A身份连接时,select * from c, 查询的是A下的c表
- set search_path = “$user”, XXX,XXX, public; 可以在一次连接中起作用,
- 如果想在XX的schema下,不带XX1的schema而访问XX1下的表,
1.执行:grant all on SCHEMA XX1 to XX;
2.将要授权的schema XX1下的表T1 授权给XX:grant select,insert,delete,update on XX1.T1 to XX
3.alter role XX set search_path to “$user”, XX, XXX1, public;
可以永久生效,使得XX在访问XXX1下的表时不用带上schema