How to find all object in a database using a script? - postgresql

Can someone help me with this? I need to find out all the objects in a database using a script. The reason why I need this is, I am asked to change the owner of all database objects so for that I need to first list down all objects.

I think you probably want REASSIGN OWNED instead. No need to identify all the objects, just the users.

If you're changing every object from role A to role B, you might like REASSIGN OWNED:
REASSIGN OWNED BY A TO B

In PostgreSQL (or almost any other RDBMS for that matter), I would recommend to take a look at metadata tables (system catalog).
Example. You want all tables:
db => \d pg_tables
View "pg_catalog.pg_tables"
Column | Type | Modifiers
-------------+---------+-----------
schemaname | name |
tablename | name |
tableowner | name |
tablespace | name |
hasindexes | boolean |
hasrules | boolean |
hastriggers | boolean |
db => select tablename from pg_tables;
Will get you a list of all tables. You can use a query to build a script to change ownership of the tables you want.
Similarly, you can query other views/tables in the catalog to get other object types (sequences, indexes, you name it).

If you can do a pg_dump and pg_restore to create a new database the adding the --no-owner flag on the pg_restore and running the pg_restore as the user you wish to set ownership to should work for this.

Related

Postgres: relation does not exist error when table exists on public schema

I have a table that was dumped to Postgres using Pandas and Pandas can read it just fine using the read_sql_table command but I can't seem to be able to access it using SQL. When I run the \dt command, I get the table listed under the public schema as one of the existing tables.
List of relations
Schema | Name | Type | Owner
--------+------------------------------------+-------+----------
public | "e7b6a2e19789418e9e48fd34e981b036" | table | postgres
But when I run SELECT * FROM "e7b6a2e19789418e9e48fd34e981b036"; I get the relation does not exist error. I have tried the following:
SELECT * FROM "e7b6a2e19789418e9e48fd34e981b036"
SELECT * FROM "public"."e7b6a2e19789418e9e48fd34e981b036"
Granted usage to public schema to the user by doing GRANT USAGE ON SCHEMA public TO postgres;
Checked this stack overflow answer that suggest it might be the identifier length is too long but my identifier length is 32 bytes with Postgres allowing up to 63 bytes by default
When I run SHOW search_path; it shows "$user", public which is what it should be but for some reason Postgres keeps saying the relation does not exist.
Other helpful information:
I'm running Postgres in a docker container from here
Any idea on what might be causing the error here?
Your table name contains double quotes.
Embedding double quotes in an identifier follows the same rules as embedding single quotes in a string literal: you need to double them:
So the table was created with something like this:
create table """e7b6a2e19789418e9e48fd34e981b036"""(...);
You need to use the same syntax when you select from it:
SELECT *
FROM """e7b6a2e19789418e9e48fd34e981b036""";

ERROR: must be owner of type character varying or type json

I need to cast varchar to json using:
CREATE CAST (character varying AS json) WITHOUT FUNCTION as ASSIGNMENT;
Connecting to Postgres with the master account of my RDS Postgres instance, I get the following error
ERROR: must be owner of type character varying or type json
The owner is rdsadmin:
\dT+ varchar
List of data types
Schema | Name | Internal name | Size | Elements | Owner | Access privileges | Description
------------+-------------------+---------------+------+----------+----------+-------------------+-------------------------------------------------------------------
pg_catalog | character varying | varchar | var | | rdsadmin | | varchar(length), non-blank-padded string, variable storage length
Now I don't have rdsadmin password, is there any other way to run this query?
I don't think you can bootstrap your way to the full rdsadmin privileges.
However it seems that you can make yourself the owner of types:
ALTER TYPE json OWNER TO myowner;
And then you can create casts for that type to your heart's content.

How to get user creation timestamp in RDS Postgres 9.3.1/9.3.2/9.3.3

I am able to get user creation timestamp in Amazon Redshift like below:
redshiftpocdb6=# select username,recordtime,valuntil from stl_userlog where username = 'u002';
username | recordtime | valuntil
----------------------------------------------------+----------------------------+------------------------------
u002 | 2014-07-23 14:36:11.314898 | 294277-01-09 04:00:54.775807
(1 row)
How to get the same info in RDS Postgres 9.3.3? This above table is not existing.
There is no automatic provision for that in PostgreSQL. You need to add a column with default value per table yourself:
ALTER TABLE stl_userlog ADD column created_at timestamp DEFAULT now()
Doesn't work for rows that are already there. That ship has sailed ...

Understanding the output of PSQL's \dp and \z

I'm having trouble selecting from a database in PSQL. This is the output of the table I'm interested in. Can someone decipher the access priveleges for me? I know that arwdRxt means append,read,write,etc... The syntax is confusing to me, what exactly do the slashes and equals mean in the access privileges column? Please let me know if my question isn't clear.
Access privileges
schema | name | type | access privileges
--------+---------------+------+-------------------------
public | table_name | view | amazonuser=arwdRxt/amazonuser+
| | | readonly=r/amazonuser
It is described in detail in the docs. The thing before the = is who has those permissions, the thing after the / is who granted those permissions.
From the docs:
Privilege Abbreviation Applicable Object Types
SELECT r (“read”) LARGE OBJECT, SEQUENCE, TABLE (and table-like objects), table column
INSERT a (“append”) TABLE, table column
UPDATE w (“write”) LARGE OBJECT, SEQUENCE, TABLE, table column
DELETE d TABLE
TRUNCATE D TABLE
REFERENCES x TABLE, table column
TRIGGER t TABLE
CREATE C DATABASE, SCHEMA, TABLESPACE
CONNECT c DATABASE
TEMPORARY T DATABASE
EXECUTE X FUNCTION, PROCEDURE
USAGE U DOMAIN, FOREIGN DATA WRAPPER, FOREIGN SERVER, LANGUAGE, SCHEMA, SEQUENCE, TYPE

Why can't I see the column names of a table?

So I made some tables programatically and I want to verify it's structure is what I think it is.
>Rocko=# \c Rocko
Password for user Rocko:
psql (8.4.4, server 8.4.8)
You are now connected to database "Rocko".
Rocko=# \d
List of relations
Schema | Name | Type | Owner
--------+--------------+----------+-------
public | Email | table | Rocko
public | Email_id_seq | sequence | Rocko
public | Test | table | Rocko
public | Test_id_seq | sequence | Rocko
public | User | table | Rocko
public | User_id_seq | sequence | Rocko
(6 rows)
So, for example, I want to see the columns in Test.
Rocko=# \d Test
Did not find any relation named "Test".
Wait a minute?! Did not Test just show up under "List of Relations"? What's going on here?
PostgreSQL converts unquoted identifiers (such as table and column names) to lower case by default; the standard says that identifiers are supposed to be normalized to upper case but that's not important here. So, when you say this:
\d Test
PostgreSQL considers that the same as \d test. You probably have a table that was created with a quoted name:
create table "Test" ( ...
so that its name is case sensitive and must be quoted (with double quotes) every time it is referenced. So try quoting the name:
\d "Test"