【问题标题】:how do I set table ownership in rails with postgresql?如何使用 postgresql 在 Rails 中设置表所有权?
【发布时间】:2012-04-30 02:05:44
【问题描述】:

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

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

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

拥有两个帐户的原因是能够快速切换,例如当我需要在不停机的情况下更改密码时。

有没有办法告诉 Rails 在创建表时使用特定角色作为所有者?(或者如果没有两个帐户在同一个 postgresql 角色中,也许有更好的方法来完成此任务?)

更新:到目前为止,我发现 this solution 可以作为外部脚本手动运行并将所有表的所有权更改为 NOLOGIN 角色,但我希望有更优雅的东西或者更适合 rails 的东西。

【问题讨论】:

    标签: ruby-on-rails-3 postgresql roles


    【解决方案1】:

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

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

    GRANT role1 TO role2;
    

    和/或,对于 PostgreSQL 9.0 或更高版本,您可以指示 PostgreSQL 在新对象上设置 default privileges

    ALTER DEFAULT PRIVILEGES 允许您设置将要使用的权限 应用于将来创建的对象。 (不影响 分配给已经存在的对象的权限。)目前,只有 表(包括视图和外部表)、序列、 和功能可以改变。

    您可以对角色或架构执行此操作。对于您的情况,您可以:

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

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

    按照这些思路:

    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 语句 需要对象的所有权。我引用the manual on ALTER TABLE

    您必须拥有该表才能使用 ALTER TABLE。

    作为拥有表工作的角色的成员。所以,在上面的例子中,如果你让role0拥有自己的表,role1role2可以使用ALTER TABLE。执行:

    ALTER TABLE tbl OWNER TO user0;
    

    对于您创建的每个表。

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

    SET ROLE user0;
    CREATE ...;
    CREATE ...;
    RESET ROLE;
    

    如果你不知道自己是谁:

    SELECT current_user, session_user;
    

    【讨论】:

    • 感谢您的快速回复。所以看第一个选项:我将有两个用户分别授予另一个用户,而不是让两个用户拥有一个“主”角色?例如GRANT user1 TO user2; GRANT user2 TO user1?每次“切换”之前都必须手动执行?如果我使用DEFAULT PRIVILEGES,但我只能执行一次。对吗?
    • GRANT 表示永久授予权限,只需要一次。
    • 对不起,我很愚蠢,但我不明白这是怎么回事。似乎赠款是分层的,例如GRANT user1 TO user2,因此 user2 将拥有与 user1 相同的权限,但反之则不然。无论哪个用户创建了表,我都需要两个用户都具有完全相同的权限。也许我错过了什么。
    • @YoavAner:我为此添加了一个建议。
    • 谢谢你没有放弃我。我尝试了你的建议,但它仍然不适用于 Rails。似乎 rails 坚持在您运行迁移时,该表由进行更改的用户拥有。它会抛出这种错误PG::Error: ERROR: must be owner of relation {table_name}
    猜你喜欢
    • 2010-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-07
    • 2015-11-30
    • 2015-01-20
    • 2021-06-26
    相关资源
    最近更新 更多