Cannot drop PostgreSQL role. Error: `cannot be dro

2020-05-31 08:52发布

问题:

I was trying to delete PostgreSQL user:

DROP USER ryan;

I received this error:

Error in query:
ERROR: role "ryan" cannot be dropped because some objects depend on it
DETAIL: privileges for database mydatabase

I looked for a solution from these threads:

  • PostgreSQL - how to quickly drop a user with existing privileges
  • How to drop user in postgres if it has depending objects

Still have the same error.

This happens after I grant all permission to user "ryan" with:

GRANT ALL PRIVILEGES ON DATABASE mydatabase ON SCHEMA public TO ryan;

回答1:

Get rid of all privileges with DROP OWNED (which isn't too obvious from the wording). The manual:

[...] Any privileges granted to the given roles on objects in the current database and on shared objects (databases, tablespaces) will also be revoked.

So the reliable sequence of commands to drop a role is:

REASSIGN OWNED BY ryan TO postgres;  -- or some other trusted role
DROP OWNED BY ryan;
-- repeat in ALL databases where the role owns anything or has any privileges!

DROP USER ryan;

Related:

  • Drop a role with privileges (with a function to generate commands for all relevant DBs)
  • Find objects linked to a PostgreSQL role


回答2:

What worked for me was 1) Connecting to the database

\c mydatabase

2) Reassigning Ownership

REASSIGN OWNED BY ryan TO <newuser>;

Or/and just deleting the object

DROP OWNED BY ryan;

3) Executing REVOKE PRIVILEGES

REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM ryan;
REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public FROM ryan;
REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public FROM ryan;

4) Dropping the user

DROP USER ryan;

PS: You might not need to execute both Step 2 and 3, just one of the two steps might be usually enough.



回答3:

Granting all permissions to ryan won't help, odds are he's the DB owner. You're going to need to make someone else own it:

REASSIGN OWNED BY ryan TO postgres;

unless you don't need mydatabase anymore, if that's the case just drop the database (MAKE SURE YOU REALLY DON'T NEED IT BEFORE DOING THIS):

DROP DATABASE mydatabase;