"No relations found" in psql after rails db:migrate succeeds - postgresql

As a Rails novice, I'm following instructions in railscast #342 to set up a postgres database connection on my Mac.
I created a new rails project with
$ rails new blog -d postgresql
I edited the database yaml file to set the username and password.
I used psql to add the new user and password, and gave it permission to create tables: alter user blog create db
I created the db via
rake db:create:all
It succeeded and inside psql, doing \l to list schemas, I see all three schemas blog_test, blog_development and blog_production
I then do
$ rails g scaffold article name content:text
all looks good
I then do
$ rake db:migrate
I get messages showing success:
$ rake db:migrate
== 20150701220010 CreateArticles: migrating ===================================
-- create_table(:articles)
-> 0.0128s
== 20150701220010 CreateArticles: migrated (0.0129s) ==========================
I set my search path to look at the schema:
set search_path to lcuff,public,blog_development;
show search_path:
search_path
---------------------------------
lcuff, public, blog_development
But trying to find the table,
# \d
No relations found.
I've done the db:migrate VERSION=0 and it successfully reports that it drops the table, and then I create it again with db:migrate and it reports success.
If the first part hadn't worked, where it actually created the schema, I'd think I'm pointed to the wrong database somehow.
Ideas?

You should first connect to the database before fetching the tables.
\connect blog_development
And then try giving \d to list all tables.
You can also try with \dt.
Example(Tested in my Project):
\connect my_db
You are now connected to database "my_db" as user "postgres".
my_db=# \d
List of relations
Schema | Name | Type | Owner
--------+-------------------------------+-------+----------
public | access_managements | table | postgres
public | amenities | table | postgres
public | city_coordinates | table | postgres
public | coapplicants | table | postgres
Source

Related

Postgres: Unable to connect to server. role 'postgres' does not exist

I am new to PostgreSQL and I just have installed pg4admin. I have found out that there are no servers, so I tried to create one, but end up with error shown on the attached screenshot.
By the way, I am able to:
sudo -i -u postgres
psql
\du
and see:
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
I will appreciate any help related to the solution regarding creating PostgreSQL server.
I'm not sure if only one of the things that I did helped or both are required, but here is what I have done:
changed port to 5433 (this seems to be something for sure needed, but I have tried this before with no luck)
I created a new role and a new OS user with the same name as the role.
With this two it worked for me.

How to login to postgreSQL at the top level?

I have Postgres 9.6 installed on mac os. When I enter the command:
$ psql (it takes me to below prompt)
bar=#
bar=# \conninfo
You are connected to database "bar" as user "bar" via socket in "/tmp" at port "5432".
How do I get out of database bar and be at the top level so that when I enter command:
CREATE DATABASE postgis_in_action;
CREATE SCHEMA ch07;
CREATE TABLE ch07.bag_o_rasters(rid serial primary key, rast_name text, rast raster);
database postgis_in_action will be created and within this database ch07 schema will be created and not nested inside database "bar" and the table will be created within ch07 schema under postgis_in_action database?
After creating the new database you need to switch to it. Otherwise the create schema will be run in the database to which you initially connected. In psql you can do that using \connect
bar=# CREATE DATABASE postgis_in_action;
bar=# \connect postgis_in_action
You are now connected to database "postgis_in_action" as user "postgres".
CREATE SCHEMA ch07;
CREATE TABLE ch07.bag_o_rasters(rid serial primary key, rast_name text, rast raster);
I would strongly recommend you create a regular user to do your work. Do not do everything as the superuser. E.g.:
bar=# create user ace password '*******';
bar=# create CREATE DATABASE postgis_in_action owner ace;
\connect postgis_in_action ace
Password for user ace:
You are now connected to database "postgis_in_action" as user "ace".
postgis_in_action=>
Maybe you have an experience with other databases, but this is the Postgres. Schemas are nested in databases, and you cannot to connect to schema (in Postgres). If you want create the database, then you use CREATE DATABASE ch07 instead CREATE SCHEMA ch06.
Instance (Postgres Cluster)
|
v
-------------------- ...
| |
v v
Database1 Database2
|
----------------------- ...
| | |
v v v
public schema1 schema2
|
----------------------- ...
| | |
v v v
table1 table2 table3
In this case the Postgres is similar to MS SQL, and very different to Oracle. Schema in Postgres and Oracle are different things.
When you connect to Postgres, then you have to specify target database. You cannot to connect just to server, or you cannot to connect to schema. Schemas (in Postgres) are like directories. You can specify an order of searching of schemas. You can set SEARCH_PATH per connect, per user or in an session (it is analogy of PATH in MS Win or UNIX).

Why I am not getting my postgres user table data, while other tables are accessible

I am working on this flask based web app. While things are working fine in the app, I wanted to verify the same in my postgres database.
While I can access user data in my app, I am not able to see the same when I try to access while SQL command on the terminal. This problem is specific to the 'user' table, while other tables could be accessed normally on terminal too.
This is the result of my user query:
classroom=# SELECT * FROM user;
user
-------
fatih
(1 row)
and this is some other table in the same database:
classroom=# SELECT * FROM course;
id | title | code
----+-----------------------------+----------
3 | Algorithms | COC2030
4 | Web development using Flask | FLASK001
(2 rows)
I am expecting the same type of result as in the course table, as in the user table.
Assuming there are more columns or rows in the user table that you'd like to see, you could try:
Log in using the same user as the flask app.
Log in as user postgres and check if that changes things (sudo -u postgres psql classroom, or psql classroom postgres.)
Use the \dp command to see if there are column privileges.
Use the \dn+ command to see if there are row security policies.

How can I change the owner of the public schema in databases created via the Google Console?

In Google's SQL Cloud Postgres service, when I create a database via the Web Console for a PostgreSQL instance, it automatically sets the owner of the database's default "public" schema to be cloudsqladmin. It seems I cannot change the ownership:
mydb=> \dn
List of schemas
Name | Owner
--------+---------------
public | cloudsqladmin
(1 row)
mydb=> alter schema public owner to postgres;
ERROR: must be owner of schema public
mydb=> \du
List of roles
Role name | Attributes | Member of
-------------------+------------------------------------------------+---------------------
cloudsqladmin | Superuser, Create role, Create DB, Replication | {}
cloudsqlagent | Create role, Create DB | {cloudsqlsuperuser}
cloudsqlreplica | Replication | {}
cloudsqlsuperuser | Create role, Create DB | {}
pg_signal_backend | Cannot login | {}
postgres | Create role, Create DB | {cloudsqlsuperuser}
mynewuser | Create role, Create DB | {cloudsqlsuperuser}
I also created a "mynewuser" through the web console, and cannot remove the "mynewuser" from the "cloudsqlsuperuser" group:
mydb=> alter group cloudsqlsuperuser drop user mynewuser;
ERROR: "cloudsqlsuperuser" can't be altered
If I wanted to create a database with a public schema that only a new user has access to (and owns), should I be doing this outside of the Google web ui? It seems like any databases I create are owned by cloudsqladmin, and any users I create are those "cloudsqlsuperuser" members. If I wanted to restrict permissions for a user, should I create that user normally via psql and bypass the web ui altogether?
From my experience, you seem to have to bypass the web ui / cli tool entirely.
When you create a database through the cli tool:
gcloud sql databases create DBNAME --instance INSTANCE
It assigns ownership to cloudsqlsuperuser, same as through the gui from the sounds of it.
When I have created a user specifically through the CLI tool:
gcloud sql users create USER 'host' --instance INSTANCE
Those users get the same permissions as cloudsqlsuperuser. In this case, it is possible to alter the ownership of the database. I had success through psql command connecting as the user I wanted to own the database and running:
ALTER DATABASE database OWNER TO user;
However if the user was created via psql (not glcoud cli), then the permission are not the same and the above failed.
I'd be tempted to create your instance, set the 'postgres' users password through the tool, then psql into the instance from there and do everything you need via sql commands. I think the tool does some things very nicely (as does the UI), but its a pain later on.
If anyone knows better, I'd love to hear how you can work with the default gcloud user.
Basically what happens here is that a usual CREATE DATABASE statement seems to create a new database based on the template0 database. This database is owned by cloudsqladmin. A role only Google has access to. When the gcloud or web GUI is used, it executes the following query:
CREATE DATABASE mydb TEMPLATE template1;
For template1 the owner is set to cloudsqlsuperuser a role that gets assigned to the postgres user, and other users created through the GUI.
So if you would like to create a database using sql with the appropriate privileges, just execute the statement above, and your public schema will then be owned by the cloudsqlsuperuser, and can be altered using the default postgres user, or other users created through the web GUI.
Connect to the database mydb by owner user (for exaple, it is mynewuser).
If you want to change the public schema owner, first you should make the user postgres owner of your database mydb:
mydb=> ALTER DATABASE mydb OWNER TO postgres;
After that, you can change the public schema owner:
mydb=> ALTER SCHEMA public OWNER TO postgres;
Besides, to remove your mynewuser from the cloudsqlsuperuser group (role) use:
mydb=> REVOKE cloudsqlsuperuser FROM mynewuser;
Note: The default postgres user in Google Cloud Platform's (GCP) Cloud SQL (PostgreSQL) is not a superuser of the instance. Also, all users created from the GCP web UI have cloudsqlsuperuser role by default, and the following attributes (privileges): CREATEROLE, CREATEDB and LOGIN. They don't have the SUPERUSER or REPLICATION attributes.

Owner of schema public changes depending on who I'm logged in as?

$ psql postgres
postgres=# \dn
List of schemas
Name | Owner
--------------------+----------
information_schema | postgres
pg_catalog | postgres
pg_toast | postgres
pg_toast_temp_1 | postgres
public | student
(5 rows)
When I log in to psql with user postgres, it shows that schema public is owned by user student. However, when I log in to psql with user student:
$ psql student
student=> \dn
List of schemas
Name | Owner
--------------------+----------
information_schema | postgres
pg_catalog | postgres
pg_toast | postgres
pg_toast_temp_1 | postgres
public | postgres
(5 rows)
It shows that schema public is owned by user postgres.
How can I get the ownership of schema public transferred to user student if the user with privileges to do so thinks that it's already done?
This is a misunderstanding. You are logging into two different databases.
When running
$ psql postgres
postgres is the name of the database. With default configuration the name of the database user is derived from the name of the system user using ident authentication automatically. The only parameter is assumed to be the database name. You do not want to change anything in the database postgres, it's a system database for maintenance tasks.
The other database is named student. Each database has a schema public with its respective owner.
Read the manual for psql or try a lowly man psql.
To transfer ownership of the schema public in the database student, log in as superuser:
psql -U postgres student
Or as operating system user postgres, just:
psql student
And run:
ALTER SCHEMA public OWNER TO student;
Details in the manual once more.