如何使用postgresql在rails中设置表所有权?

how do I set table ownership in rails with postgresql?

我对rails非常陌生,所以希望这不是一个愚蠢的问题。

我试图让rails使用带有两个不同用户帐户的postgresql数据库。但是我希望能够在这些帐户之间切换,因此它们对数据库具有相同的权限(理想情况下它们都不是postgresql超级用户)。

我在postgres中创建了一个NOLOGIN角色,这是数据库的所有者。然后为此角色分配了两个用户帐户。但是,每当我执行rake db:migrate时,它将使用户帐户(而不是角色)成为表的所有者。如果我然后切换用户,则第二个用户将对第一个用户创建的表没有正确的权限。

拥有两个帐户的原因是能够快速切换,例如当我需要更改密码而没有停机时间。

有没有办法告诉rails在创建表时使用特定角色作为所有者? (或者,如果没有两个帐户在同一个postgresql角色中,有更好的方法可以实现这一点吗?)

更新:到目前为止,我发现这个解决方案是作为外部脚本手动运行并将所有表的所有权更改为NOLOGIN角色,但我希望有更优雅或适合rails的更好的东西。


你可以在PostgreSQL方面做很多事情:

如果您希望role2拥有role1拥有的所有权限,您可以:

1
GRANT role1 TO role2;

和/或使用PostgreSQL 9.0或更高版本,您可以指示PostgreSQL为新对象设置默认权限:

ALTER DEFAULT PRIVILEGES allows you to set the privileges that will be
applied to objects created in the future. (It does not affect
privileges assigned to already-existing objects.) Currently, only the
privileges for tables (including views and foreign tables), sequences,
and functions can be altered.

您可以为角色或模式执行此操作。对于您的情况,您可以:

1
ALTER DEFAULT PRIVILEGES FOR ROLE role1 GRANT SELECT ON TABLES TO role2;

如果您希望多个不同的角色共享一组权限,我会将对象的所有权限授予一个非登录角色(以前称为GROUP) - 在下面的示例中为role0。使用DEFAULT PRIVILEGES,不要忘记预先存在的对象,包括序列(我倾向于忘记那些)。
然后GRANT role0到那些其他角色。

沿着这些方向:

1
2
3
4
5
6
ALTER DEFAULT PRIVILEGES FOR ROLE role1 GRANT SELECT ON TABLES TO role0;
ALTER DEFAULT PRIVILEGES FOR ROLE role2 GRANT SELECT ON TABLES TO role0;
...

GRANT role0 TO role1;
GRANT role0 TO role2;

这样,如果需要,您可以轻松地GRANT只有一个角色的附加权限。
您可以在此设置中添加任意数量的角色。

许多DML语句需要对象的所有权。我引用ALTER TABLE上的手册:

You must own the table to use ALTER TABLE.

作为拥有该表的角色的成员也是如此。因此,在上面的示例中,如果您创建role0自己的表,role1role2可以使用ALTER TABLE。执行:

1
ALTER TABLE tbl OWNER TO user0;

对于您创建的每个表。

或者在运行CREATE命令之前进入角色:

1
2
3
4
SET ROLE user0;
CREATE ...;
CREATE ...;
RESET ROLE;

如果你忘记了自己的身份:

1
SELECT CURRENT_USER, session_user;