Rails: PG::InsufficientPrivilege: ERROR: permission denied for relation schema_migrations Rails:PG :: InsufficientPrivilege:错误:拒绝对关系模式迁移的权限

36

我正在尝试在Rails中创建数据库。在Postgres中,我看到开发和测试数据库,但是出现了权限错误。我尝试遵循这个链接,但对我没有用。

Error: PG::InsufficientPrivilege: ERROR: permission denied for relation schema_migrations : SELECT "schema_migrations".* FROM "schema_migrations"

Rails:permission denied for relation schema_migrations

default: &default
  adapter: postgresql
  encoding: unicode
  pool: 5
  host: localhost
  username: root
  password:

development:
  <<: *default
  database: svp-chicago_development

我登录到Postgres并执行了这些命令。

psql postgres
CREATE USER root
CREATE DATABASE svp-chicago_development
GRANT ALL PRIVILEGES ON DATABASE svp-chicago_development to root
ALTER DATABASE svp-chicago_development OWNER TO root
当我执行\list时,我看到数据库在那里。

可能是密码问题;尝试创建一个带有密码的root用户,并将其包含在config/database.yml文件中。 - Prakash Murthy
在这里记录我最近的脑抽,以防对其他人有所帮助 :) 我正在Render.com上设置一个Rails应用程序,并在他们的shell中运行“bin/rails db:create”时遇到了“PG :: InsufficientPrivilege”。然后意识到我已经通过他们的UI创建了DB,并且我想要的是“bin/rake db:schema:load”。 - Henrik N
10个回答

67

我曾经遇到同样的问题,通过将角色添加为"Superuser"来解决。

首先,列出用户及其权限。如果按照上述命令操作,root用户没有"Superuser"属性。

postgres=# \du
                                   List of roles
 Role name |                         Attributes                         | Member of
-----------+------------------------------------------------------------+-----------
 other     | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 root      |                                                            | {}

接下来,将root用户升级为“超级用户”。

postgres=# ALTER USER root WITH SUPERUSER;
ALTER ROLE

再次列出用户及其权限。现在root拥有“超级用户”权限。

postgres=# \du
                               List of roles
 Role name |                         Attributes                         | Member of
-----------+------------------------------------------------------------+-----------
 other     | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 root      | Superuser                                                  | {}

希望能对你有所帮助。


3
注意:这种解决方法存在 危险性,使用时应谨慎。 - Kevin Cooper

14

我猜你忘记为你的用户创建了密码。请尝试按以下方式创建密码:

CREATE USER root WITH PASSWORD 'your_new_password';
CREATE DATABASE svp-chicago_development;
GRANT ALL PRIVILEGES ON DATABASE svp-chicago_development to root;
ALTER DATABASE svp-chicago_development OWNER TO root;

1
我已经尝试了这个方法,但我的Postgres仍然出现相同的错误。您能否请看一下此链接(http://stackoverflow.com/questions/41424654/postgres-permission-denied-for-relation-schema-migrations)? - Code-MonKy
以下答案对我有用:在PostgreSQL中同时修改所有表的OWNER - ddreliv

12

我在使用Rails 6应用程序与PostgreSQL时遇到了这个问题。

第一步检查是确保你已经为特定用户授予数据库的所有权限,可以使用以下命令:

GRANT ALL PRIVILEGES ON DATABASE mydatabase TO myusername;

然而在我的情况下,问题的原因是我创建了一个数据库并将所有权限授予特定的用户。过了一段时间后,我使用GRANT ALL PRIVILEGES ON DATABASE mydatabase TO myusername;将另一个用户也赋予了这些权限

所以尽管我已经将所有权限授予第二个用户,但它仍然没有权限对数据库表执行操作。

以下是我解决问题的步骤:

登录存储数据库的PostgreSQL控制台:

sudo -u postgres psql

列出该 PostgreSQL 数据库服务器中的所有数据库:

\l

或者

\list

连接到您想要修复其权限的数据库:

\c mydatabase

或者

\connect mydatabase

使用您的 search_path 列出当前数据库中的所有表:

\dt

列出当前数据库中的所有表,无论你的 search_path 是什么:

\dt *.

你会注意到表格仍然将最初的userrole作为owner引用。

现在,您需要修改表格以将新的userrole作为owner引用。

您可以使用以下方法单独修改每个表格:

ALTER TABLE table_name OWNER TO new_owner;

当用户是 postgres (默认数据库用户)且您想将所有者更改为新用户时,不需要指定 old_owner。这是必要的。

或者使用以下方法同时修改所有表:

REASSIGN OWNED BY old_owner TO new_owner;

这需要指定old_owner。当你已经将用户从postgres(默认数据库用户)修改为另一个用户,并且想要将所有者修改为新用户时,这是必需的。

注意:确保连接到要修改特权/权限的数据库,否则可能会遇到错误。


1
这正是我所面临的问题,我首先使用我的 Mac 操作系统用户创建了数据库,然后我创建了另一个用户,但它无法对该数据库执行任何操作,因此我不得不按照所有这些步骤来“重新分配”所有者用户,这样就可以正确地工作了。谢谢! - alexventuraio

9

此外,如果您正在使用像Heroku这样的服务,请检查是否已超出行限制并且数据库中的写访问已被撤销。

您可以通过进入仪表板,点击应用程序,点击postgres服务图标,然后检查行限制来完成此操作。


2

如果有其他人遇到同样的问题,我尝试了许多其他解决方案,但对我最有效的是以下方法:在PostgreSQL中同时修改所有表的OWNER

  • 这个方法适用于我的用户(如rootpostgres)拥有Superuser权限,因此尝试使用REASSIGN OWNED会在尝试分配system对象时产生错误。
  • ALTER DATABASE无法解决问题,因为问题在于表对象的所有权,而不是数据库的所有权。更改数据库的所有者不会传播到该数据库架构中的其他对象。

1
这是我修复它的方法:
登录存储数据库的PostgreSQL控制台:
sudo -u postgres psql
列出该PostgreSQL数据库服务器中的所有数据库:
\l
或者
\list
连接到您想要修复其权限的数据库:
\c mydatabase 或者
\connect mydatabase 使用您的search_path列出当前数据库中的所有表:
\dt
或者
无论您的search_path如何,都会列出当前数据库中的所有表:
\dt *。
然后给表授予权限:-
一个表
GRANT ALL PRIVILEGES ON TABLE side_adzone TO jerry;
模式下的所有表
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO jerry;

1

向角色添加"超级用户"是一个安全问题,超级用户不仅可以删除由OP指出的svp-chicago_development数据库,还可以删除任何其他现有数据库。

我认为OP遇到的问题与@kevin-cooper指出的表所有者有关。

即使OP执行了授予数据库所有权限和所有者的命令,如果OP仍然使用postgres凭据运行任何表创建或还原转储,则在数据库svp-chicago_development上的表将具有postgres作为所有者,如果应用程序在使用其他用户/角色运行,则会引发OP提到的错误。

您可以通过以下方式在psql中检查是否存在此情况:

\c svp-chicago_development

然后列出表:

\dt

它会显示类似于:

这样的内容


 Schema |    Name    | Type  |  Owner   
--------+------------+-------+----------
 public | table_name | table | postgres

如果您只有几行数据,您可以手动更改每一行的所有者,方法是运行:

ALTER TABLE table_name OWNER TO new_owner;

如果您正在运行 pg_restore,请确保传递 --role,以便对象归属于指定的角色。


1
尝试列出你的表格以查看所有者是谁。在我的情况下,我通过 psql < dump.sql 导入了数据,所有导入的表格都由 postgres 而不是我的用户拥有。
要检查这一点,请启动 psql 并在你的数据库中输入命令 \dt。查找以下行:
public | schema_migrations | table | postgres

不好!它被 postgres 拥有,你需要解决这个问题:

  1. 你可以使用 @ddreliv 的 solution 在每个表上重新分配所有者,或者
  2. 如果你有一个备份文件,只需删除数据库并使用适当的用户重新导入它。例如,使用 sudo -u my_user psql < dump.sql 而不是 sudo -u postgres psql < dump.sql

0

对于我们的情况(使用docker-compose),

删除Postgres数据

$ docker-compose down # CAUTION: may cause data loss
$ docker volume rm XXX_DB_VOLUME # CAUTION: will cause data loss

然后在docker-compose.yml中将Postgres从11.11降级到11.8

xxx_db:
  image: "postgres:11.8"

最后重新启动Postgres Docker

$ docker-compose up -d

问题已解决。


0

解决方案 A

我曾遇到过类似的问题,因为我正在自动恢复一些数据库,但它没有得到正确地设置(在权限方面,它是用错误的用户创建的)。

我的解决方案是删除这些数据库,并使用正确的用户创建每个数据库:

createdb mydb -U username (或只需使用该用户登录 psql 并在那里创建它们)

然后再执行相应的操作。

pg_restore --dbname=mydb -d mydb mydb.pgr

它像魔法一样运行良好。


方案B

如果这不起作用,那么您的用户可能只需要更多的权限。将所需的用户名升级为“超级用户”。

postgres=# ALTER USER username WITH SUPERUSER;

通过获取用户列表及其权限来确认更改已生效

postgres=# \du

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接