【问题标题】:PostgreSQL Prevent updating columns EVERYONEPostgreSQL 防止更新列 EVERYONE
【发布时间】:2015-02-09 16:57:01
【问题描述】:

我想阻止用户(每个人)更新主题的特定列以防止循环依赖。

CREATE TABLE Topic(
    id          serial    NOT NULL PRIMARY KEY,
    contenxt    text      DEFAULT NULL, -- can be freely updated
    Dependency1 serial    REFERENCES Topic(id) ON DELETE RESTRICT, -- CAN'T be updated
    Dependency2 serial    REFERENCES Topic(id) ON DELETE RESTRICT, -- CAN'T be updated
);

DENY UPDATE ON Topic(Dependency1) TO *; -- Here
DENY UPDATE ON Topic(Dependency2) TO *;

但是在尝试了几个变种之后,它似乎总是报告一些语法错误。修复它开始变得无聊。欢迎使用替代解决方案,但我认为该解决方案相当简单(假设您知道该 u.u 的确切语法)。

在 cmets 中建议使用触发器,但我不知道如何使用触发器来实现。

【问题讨论】:

  • 触发器怎么样?有了它,您也可以阻止超级用户的更新。
  • 主题表有其他可以更新的字段(“内容”作为文本),因此触发器应该只记录对“依赖项”字段的更改。如果不可能,请告诉我将“内容”移动到另一个表。只是我从来没有那样使用过触发器,所以我不知道从哪里开始
  • 查看答案。在 postgresql 中,您可以在列上使用触发器。您也可以仅在价值确实不同时才提出信息。如果需要..
  • DENY 不被 PostgreSQL 使用,它不能工作。只需阅读有关 REVOKE(和 GRANT)的手册:postgresql.org/docs/current/interactive/sql-revoke.html 使用 TRIGGER 是一个非常奇怪的解决方法,因为它应该使用正确的权限来完成。
  • “但是在尝试了几个变体之后,它似乎总是报告一些语法错误。修复它开始变得很无聊。” 在线提供语法。您似乎没有尝试阅读它。 (PostgreSQL 使用revoke,而不是deny。)

标签: postgresql privileges


【解决方案1】:

试试这个:

CREATE OR REPLACE FUNCTION fnprevent_update()
  RETURNS trigger AS
$BODY$
    BEGIN
        RAISE EXCEPTION 'no way';
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;



CREATE TRIGGER trg_prevent_update
  BEFORE UPDATE OF dependency1, dependency2
  ON topic
  FOR EACH ROW
  EXECUTE PROCEDURE fnprevent_update();

只需自定义“没办法”消息。

【讨论】:

  • 非建设性评论家,如果您知道答案存在,请展示出来。
  • @FrankHeikens,实际上触发器会阻止超级用户修改数据。这将防止权限中的错误和未来的错误配置。还不错:-)
  • @user_0:不,它没有,超级用户总是可以更新记录。他可能必须更改他的权限或禁用触发器,但这始终是可能的。当您有权解决此问题时,触发器不是一个好主意。
  • @FrankHeikens 是的,他可以。但他需要禁用触发器。这意味着一个有意识的决定。只要得到许可,他就可以。我错了吗?我不会假装这是解决方案,但在我看来,这似乎是适合这种情况的最佳解决方案。您的提案的问题是:您如何防止 SUPERUSER 进行意外更新?
  • 假设超级用户只是 1,就像在中小型项目中发生的那样,并且他或她拥有项目的所有专业知识并不总是需要的。也不假设他或她将成为一流的 dba。权限解决方案假定,是正统的解决方案,它适用于 99%。但是给定的解决方案是针对非正统项目的非正统项目,通常是大型项目。本身还不错。这就像在环境中禁用 root 或 sudo 组用户的读取或写入。是的,他们可以改变这一点并继续这样做,但是当他们看到他们被禁用时,他们会被警告这是有原因的。
【解决方案2】:

PostgreSQL 支持列级权限。你可能需要这些方面的东西。

grant select(id, dependency1, dependency2), update(id) on topic to public;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-15
    相关资源
    最近更新 更多