how to display tables under a particular schema in a pSQL session? - psql

In a pSQL session (linux server), the command \dn displays the schemas in a database. Is there any command that could display tables just under a particular schema, say xyz?
Thanks,

\dt is used to list tables. By default it will list those in the current schema.
You can, however, pass a pattern to it. In your case, you want to do:
\dt xyz.
This will list all tables in the xyz schema.
Here's some further things you can do with it:
list all tables in all schemas: \dt *.
list tables with user in their name: \dt *user*
list tables with user in their name in all schemas: \dt *.*user*

The "\z" COMMAND use to list of tables when inside the interactive psql session.
# psql -d mcdb -U admin -p 5555
mcdb=# \z

Related

Duplicating Ruby on Rails 5 project with PostgreSQL database

I have a Project-A, and I'm starting Project-B. I want to use Project-A as a starting point. So I copied the files, but how can I duplicate the database? Thank you!
The exact command depends on what type of database you are copying from and too, also on whether you want to copy the structure only or the structure and the content.
A general way to do this would be to export the Project-A database into an SQL file, then run that SQL file through the project-B database. The SQL file can store the structure, or the content or both - you choose when you do the export.
Postgresql uses the command pg_dump to export to SQL. The accepted answer in the question linked to in jdgray's comment shows how the output of pg_dump can be piped directly into the second database so that no intermediate file is created.
To get your database
pg_dump -Fc mydb > db.dump
To restore it:
pg_restore -d <you_new_db_name> /db.dump
This is assuming you are going from pg to pg. All data and structure and relationships will come over with this. I would suggect using pgadmin4 to make the new db before hand so you can just import over to it. In your database.yml change the db name.
If you need addition stuff, like declaring which ip address your db is on use the -p flag. Here is the link to more flags (Postgres v 9.6):
Postgres Link
I just edited the db name from database.yml and ran rake db:create db:migrate

Rails: PG::InsufficientPrivilege: ERROR: permission denied for relation schema_migrations

I'm trying to create the database in Rails. In Postgres I see the development and test database, however, I'm getting a permissions error. I've tried to follow this link, didn't work for me.
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
I log into postgres and did these commands.
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
When I do \list I see the database is there.
I had same issue and I solved by adding "Superuser" to the role.
First, list users and their privileges. If you followed above commands, root user does not have "Superuser" Attributes.
postgres=# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
other | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
root | | {}
Next, upgrade root to be a "Superuser".
postgres=# ALTER USER root WITH SUPERUSER;
ALTER ROLE
Again, list users and their privileges. Now root has "Superuser".
postgres=# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
other | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
root | Superuser | {}
Hope it helps.
I guess you missed create password for your user. Try to create password as following:
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;
I had this issue when working on a Rails 6 application with PostgreSQL.
The first check is to ensure that you've granted all privileges for a database to the particular user that you want using:
GRANT ALL PRIVILEGES ON DATABASE mydatabase TO myusername;
But in my own case, the cause of the issue was that I created a Database and then granted all privileges to a particular user. After some time, I granted another user the privileges using GRANT ALL PRIVILEGES ON DATABASE mydatabase TO myusername;
So the second user even though I granted all privileges to it, didn't have permissions to perform actions on the database tables.
Here's how I fixed it:
Log into the PostgreSQL console where the database is stored:
sudo -u postgres psql
List all databases in that PostgreSQL database server:
\l
OR
\list
Connect to the database that you want to fix it's permissions:
\c mydatabase
OR
\connect mydatabase
List all tables in the current database using your search_path:
\dt
OR
List all tables in the current database regardless of your search_path:
\dt *.
You will notice that the tables still reference the initial user or role as the owner.
Now you will have to modify the tables to reference the new user or role as the owner.
You can modify each table individually using this:
ALTER TABLE table_name OWNER TO new_owner;
This does not require specifing the old_owner. It is essential when the user is postgres (the default database user) and you want to modify the owner to a new user.
OR modify all the tables simultaneously using this:
REASSIGN OWNED BY old_owner TO new_owner;
This requires specifing the old_owner. It is essential when you have already modified the user from postgres (the default database user) to another user and you want to modify the owner to a new user.
Note: Ensure that you are connected to the database that you want to modify privileges/permissions for, else you might run into errors.
Also, if you're using a service like Heroku, it's worth checking to see if you have overrun your row limit and write access has been revoked in the database.
You can do that by going to the dashboard, click on the app, click on the postgres service icon, then check the row limit.
Just in case someone else comes here with the same issue, I did try many other solutions and the one that worked for me the best was the following: Modify OWNER on all tables simultaneously in PostgreSQL
This worked since my user (e.g. root or postgres) had Superuser privileges so trying REASSIGN OWNED gives error when trying to assign system objects
ALTER DATABASE didn't work since the issue is on a table object ownership and not in the DB ownership. Altering the owner on the DB doesn't propagate to the other object on that DB schema
Try listing your tables to see who the owner is. In my case, I had imported data via psql < dump.sql and all the imported tables were owned by postgres instead of my user.
To check this, start psql and enter the command \dt within your database. Look for the following line:
public | schema_migrations | table | postgres
Not good! It's owned by postgres and you'll need to fix that:
You can use #ddreliv's solution here to reassign the owner of every table, or
if you have a dump, simply drop the database and re-import it with the proper user. For example, use sudo -u my_user psql < dump.sql instead of sudo -u postgres psql < dump.sql.
Here's how I fixed it:
Log into the PostgreSQL console where the database is stored:
sudo -u postgres psql
List all databases in that PostgreSQL database server:
\l
OR
\list
Connect to the database that you want to fix it's permissions:
\c mydatabase
OR
\connect mydatabase
List all tables in the current database using your search_path:
\dt
OR
List all tables in the current database regardless of your search_path:
\dt *.
Then giving privilleages to the table :-
One Table
GRANT ALL PRIVILEGES ON TABLE side_adzone TO jerry;
All Tables of schema
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO jerry;
for our case (with docker-compose)
remove postgres data
$ docker-compose down # CAUTION: may cause data loss
$ docker volume rm XXX_DB_VOLUME # CAUTION: will cause data loss
then downgrade postgres from 11.11 to 11.8 in docker-compose.yml
xxx_db:
image: "postgres:11.8"
finally start postgres docker again
$ docker-compose up -d
Problem solved.
Adding "Superuser" to the role is a security issue, superusers can drop databases not only the svp-chicago_development pointed out by the OP but any other database existent.
I believe the issue that OP have is related to tables owner as pointed out by #kevin-cooper.
Even if the OP did the commands that he said granting all privileges and owner to the database, if the OP still runs any table creation or restore dump with the postgres credential the tables on the database svp-chicago_development it will have postgres as owner and if the application in running with other user/role it will throw the error mentioned by the OP.
You can check if that's the case in psql by:
\c svp-chicago_development
then listing the tables:
\dt
It will show something like:
Schema | Name | Type | Owner
--------+------------+-------+----------
public | table_name | table | postgres
If you have a few rows you can manually change the owner of each row by running:
ALTER TABLE table_name OWNER TO new_owner;
If you are running a pg_restore make sure to pass --role so objects will be owned by the role specified.

Download partial database from heroku

I have a ruby on rails application hosted on heroku using postgresql as its database. Since the database is getting pretty large, I was wondering if there's a way to download only a specific part of it off of heroku. For example, is it possible to download only one specific table, or download only rows with parent_id == x.
In addition to Steve's quite correct answer, you also have the option of connecting using psql to the DATABASE_URL and using \copy, e.g.
$ psql "$(heroku config:get DATABASE_URL)"
mydb=> \copy mytable TO 'mytable.csv' WITH (FORMAT CSV, HEADER)
mydb=> \copy (SELECT col1, col2 FROM mytable2 WHERE ...) TO 'mytable2_partial.csv' WITH (FORMAT CSV, HEADER)
You can extract whole tables, or the output of arbitrary queries (including joins etc). The table definition (DDL) is not exported this way, but can be dumped with pg_dump --schema-only -t ....
Using the DATABASE_URL config setting you can use pg_dump to access your database and use the -t switch to specify a certain table.
For example, to export the table my_table into file called db.sql:
pg_dump -t my_table `heroku config:get DATABASE_URL` > db.sql
If you need to limit the download to certain rows then I don't think pg_dump will do the job on it's own. You could create another table in your Heroku database to first define the subset of rows that you want to download and then have pg_dump dump only that table. See this question for some ideas about how to do that: Export specific rows from a PostgreSQL table as INSERT SQL script

PG::UndefinedObject: ERROR: type "hstore" does not exist but it does

First of all, this may look like a duplicate of:
postgres hstore exists and doesn't exist at same time
but it is not. While I am getting the same error message in the circumstance. When checking to see if hstore is installed on the DB, we can see that it is:
./psql -d photographerio_development -c '\dx'
List of installed extensions
Name | Version | Schema | Description
---------+---------+------------+--------------------------------------------------
hstore | 1.2 | hstore | data type for storing sets of (key, value) pairs
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
and it is too on the template_1 DB.
So, when I try to run the migration to add the hstore, I get the PG::Error: ERROR: extension "hstore" already exists and when I comment out this migration, on the next one, which requires the hstore, it says PG::UndefinedObject: ERROR: type "hstore" does not exist which is a bit of a paradox.
It is a Rails 4.0.1 app with postgresql 9 and I have hstore working on a few other projects running on this machine.
You have installed the hstore extension in a schema named hstore which is presumably not on your default search_path.
You must do one of these:
Add hstore to search_path during connection setup;
Add hstore to search_path with an ALTER USER ... SET or ALTER DATABASE ... SET;
Move the hstore extension from the hstore schema into public; or
schema-qualify all references to hstore, e.g. hstore.hstore(...). This must be done for operators too; -> becomes OPERATOR(hstore.->)
This is how I solved the problem.
Create a schema called extensions and grant authorization to the db username you use in the project.
psql -U postgres -d template1 -c "CREATE SCHEMA extensions AUTHORIZATION <yourDbUserName>;"
create the extensions in the created schema (extensions)
psql -U postgres -d template1 -c "CREATE EXTENSION IF NOT EXISTS hstore SCHEMA extensions;"
This is how I solved this issue in ubuntu 18.04.
Provide postgres super user access.
sudo su postgres
Then I run:
psql -U postgres your_database_name -c 'create extension hstore;'
Now I can alter table your_database_name and add hstore type columns in it.
Connect to your database
psql -d your_database_name -U your_user_role
And
alter table your_table_name add your_column_name HSTORE;
Though there might be saveral different ways to do it, but I solve it in this way.
Hope this will help novice users like me.

I am missing a migration file

Can I add the migration file, but tell rails not to run it locally? I need the file for others to setup the application locally.
If you have a file:
db/migrate/20121010100909_modify_table_x.rb
You can go into your database and run the following SQL.
MySQL:
INSERT INTO 'schema_migrations' VALUES ('20121010100909');
PostgreSQL:
INSERT INTO schema_migrations VALUES ('20121010100909');
And it will then ignore that migration.
Edit - How to "go into your database"
Using the parameters from config/database.yml in Rails, connect to the database you are using.
You will need to use the command-line tool of whatever database software you're using. E.g.
For PostgreSQL:
psql -d <database_name> -U <username>
For MySQL:
mysql -u <username> <databasename>#localhost -p
Type in your password if required.
Then type in and execute the SQL above.
You could insert the proper timestamp into the schema_migrations table locally.

Resources