Django: permission denied when trying to access database after restore (migration) - django

I have a django 1.4 app with a populated postgres 9.1 database in development server locally. After successful deployment, I wanted to move the data from local to online database, so I used:
pg_dump -f dump.sql -Ox database
and then restored on the server with:
psql -1 -f dump.sql database
Now trying to login online to the website admin throws a "permission denied for relation django_session" exception. I've tried to dump the data with/without -Ox switch and all its combinations but without success. I am also dropping the database and recreating it from scratch on the server with the correct owner as set in settings.py.
If I run a normal syndb without a restore then everything works well.
Am I missing something here?

It turns out that you should grant explicit ownership of all objects in the database to the owner after restore. The owner is not a superuser. It's not enough to only set the owner at database creation time. The final solution for migration goes like this:
on the client:
pg_dump -f dump.sql -Ox database
on the server:
su postgres
dropdb database
createdb database -O user
psql database -f dump.sql
and then to set the privileges:
psql database -c "GRANT ALL ON ALL TABLES IN SCHEMA public to user;"
psql database -c "GRANT ALL ON ALL SEQUENCES IN SCHEMA public to user;"
psql database -c "GRANT ALL ON ALL FUNCTIONS IN SCHEMA public to user;"
Note that we could've run the sql command in psql console but this form is easily embeddable in scripts and such.

Try to do this from postgres user:
sudo su - postgres
pg_dump -f dump.sql -Ox database
Or just pass -U flag:
pg_dump -f dump.sql -Ox database -U postgres

Here's how I fixed mine. I saved myself a ton of a headache by simply changing the user to match the current logged in user of the destination server where the import will happen.
In my case, the imported db had a user of x (x was also the username for the machine it was running on), and the destination machine had a username of y, and a postgres user of y too.
Therefore, I simply changed the Database User and Password in my Django settings to match the destination machine's y user details.
Then did this:
$ sudo -u postgres psql
psql > GRANT ALL PRIVILEGES DATABASE ON mydb TO y;
Sipping some kool-aid now!

Related

How to use pg_restore with AWS RDS correctly to restore postgresql database

I am trying to restore my Postgresql database to AWS RDS. I think I am almost there. I can get a dump, and recreate the db locally, but I am missing the last step to restore it to AWS RDS.
Here is what I am doing:
I get my dump
$ pg_dump -h my_public dns -U myusername -f dump.sql myawsdb
I create a local db in my shell called test:
create database test;
I put the dump into my test db
$ psql -U myusername -d test -f dump.sql
so far so good.
I get an error: psql:dump.sql:2705: ERROR: role "rdsadmin" does not exist, but I think I can ignore it, because my db is there with all the content. (I checked with \list and \connect test).
Now I want to restore this dump/test to my AWS RDS.
Following this https://gist.github.com/syafiqfaiz/5273cd41df6f08fdedeb96e12af70e3b
I now should do:
pg_restore -h <host> -U <username> -c -d <database name> <filename to be restored>
But what is my filename and what is my database name?
I tried:
pg_restore -h mydns -U myusername -c -d myawsdbname test
pg_restore -h mydns -U myusername -c -d myawsdbname dump.sql
and a couple of more options that I don't recall.
Most of the times it tells me something like: pg_restore: [archiver] could not open input file "test.dump": No such file or directory
Or, for the second: input file appears to be a text format dump. Please use psql.
Can somone point me into the right direction? Help is very much appreciated!
EDIT: So I created a .dump file using $ pg_dump -Fc mydb > db.dump
Using this file I think it works. Now I get the error [archiver (db)] could not execute query: ERROR: role "myuser" does not exist
Command was: ALTER TABLE public.users_user_user_permissions_id_seq OWNER TO micromegas;
Can I ingore that?
EDIT2: I got rid of the error adding the flags--no-owner --role=mypguser --no-privileges --no-owner
Ok, since this is apparently useful to some I will post - to the best of what I remember - an answer to this. I will answer this more broadly and not too AWS-specific because a) I don't use this instance anymore and b) I also don't remember perfectly how I did this.
But I gained experience with PostreSQL and since AWS RDS was also just a postgres instance the steps should work quite similar.
Here are my recommended steps when restoring a postgreSQL DB instance:
Pull the backup in a .dump-format and not in .sql-format. Why? The file-size will be smaller and it is easier to restore. Do this with the following command:
pg_dump -h <your_public_dns_ending_with.rds.amazonaws.com> -U <username_for_your_db> -Fc <name_of_your_db> > name_for_your_backup.dump
Now you can restore the backup easily to any postgreSQL instance. In general I'd recommend to set up a fresh DB instance with a new username and new databasename. Let's say you have a DB that is called testname with superuser testuser. Then you can just do:
pg_restore --no-owner --no-privileges --role=testuser -d testname <your_backup_file.dump>
And that should restore your instance.
When restoring to AWS or to any remote postgreSQL instance you will have to specify the host with the -h-flag. So this might be something like:
pg_restore -h <your_public_dns_ending_with.rds.amazonaws.com> -p 5432 --no-owner --no-privileges --role=testuser -d testname <your_backup_file.dump>
If you have a DB-instance running on a remote linux server, the host will be be your remote IP-address (-h <ip_od_server>) and the rest will be the same.
I hope this helps. Any questions please comment and I'll try my best to help more.

Unable to restore sql file in postgresql on windows

I'm trying to import sql file in postgresql but unable to do. I tried pgAdmin 4 to restore sql file. I get the error (pg_restore: [archiver] input file does not appear to be a valid archive).
I've also tried to do this with the command prompt but unable to do.
If I do
D:\Program Files (x86)\PostgreSQL\9.1\bin>psql -h 127.0.0.1 -U postgres gorkha < D:/gorkha.sql
It returns
SET
SET
SET
SET
SET
CREATE EXTENSION
COMMENT
REVOKE
REVOKE
GRANT
GRANT
Create a DB like (Employees)
Lets say you have a employees.sql file which you want to restore
postgres is your username
AT command prompt you are in the same folder with employees.sql
Code sample is:
psql -U postgres -d Employees < employees.sql
Follow This Steps:
Open pgAdmin and open Servers -> PostgreSQL 14 -> Databases,
And Choose your DB and right click and click on the PSQL Tool
If you not set your binary path and you get this alert
and click File option in top of pgadmin & open preference
Click The file icon and set the following path and Save
Final Step Open your Sql File in VSCode or note pad and copy then paste it on the PSQL Tool in pgAdmin
Its Work For Me
If any Error and Convert SQL To PGSQL (more online tools are available)
and the copy paste in to PSQL Tool in pgAdmin
use this command to restore an archived backup using pg_restore
pg_restore -U <username> -d <dbname> -1 <filename>.sql
for text/sql based backup you can try
psql -U <username> -d <dbname> -1 -f <filename>.sql

postgresql, ERROR: permission denied for relation django_migrations

i'm having troubles trying to make script to auto backup my db of my django app.
This is how i create my db for my app:
sudo -u postgres psql
CREATE DATABASE dapp;
CREATE USER backupu WITH PASSWORD 'pass123';
ALTER ROLE backupu SET client_encoding TO 'utf8';
ALTER ROLE backupu SET default_transaction_isolation TO 'read committed';
ALTER ROLE backupu SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE dapp TO backupu;
\q
And this is my backup script, backup.sh with chmod 777:
export PGUSER='backupu'
export PGPASSWORD='pass123'
TODAY=`date +%Y-%m-%d`
TIME_NOW=`date +%H:%M`
ARCH_RESP=$TODAY-$TIME_NOW
pg_dump dentalapp > /home/backupu/backup/backup_$ARCH_RESP.sql
find /home/backupu/backup/ -name '*.sql' -mtime +2 -exec rm -f {} \;
unset PGUSER
unset PGPASSWORD
But when i run it, i get this error:
pg_dump: [archiver (db)] query failed: ERROR: permission denied for
relation django_migrations pg_dump: [archiver (db)] query was: LOCK
TABLE public.django_migrations IN ACCESS SHARE MODE
and:
connection to database "dapp" failed: FATAL: Peer"authentication
failed for user "backupu"
I tried adding this line to my pg_hba.conf
local all backupu md5
But the error persist, maybe some permissions are missing or need a more step when i create my db. I already checked some other post here in stackoverflow but also without success, Can you help me?
i'm running a local server with ubuntu 14.04, nginx, gunicorn and postgresql 9.3
What happens is that you are using a user that has no permission over the django_migrations table.
Use the same data base user that the webapp uses.

Migrate postgres dump to RDS

I have a Django postgres db (v9.3.10) running on digital ocean and am trying to migrate it over to Amazon RDS (postgres v 9.4.5). The RDS is a db.m3.xlarge instance with 300GB. I've dumped the Digital Ocean db with:
sudo -u postgres pg_dump -Fc -o -f /home/<user>/db.sql <dbname>
And now I'm trying to migrate it over with:
pg_restore -h <RDS endpoint> --clean -Fc -v -d <dbname> -U <RDS master user> /home/<user>/db.sql
The only error I see is:
pg_restore: [archiver (db)] Error from TOC entry 2516; 0 0 COMMENT EXTENSION plpgsql
pg_restore: [archiver (db)] could not execute query: ERROR: must be owner of extension plpgsql
Command was: COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
Apart from that everything seems to be going fine and then it just grinds to a halt. The dumped file is ~550MB and there are a few tables with multiple indices, otherwise pretty standard.
The Read and Write IOPS on the AWS interface are near 0, as is the CPU, memory, and storage. I'm very new to AWS and know that the parameter groups might need tweaking to do this better. Can anyone advise on this or a better way to migrate a Django db over to RDS?
Edit:
Looking at the db users the DO db looks like:
Role Name Attr Member Of
<user> Superuser {}
postgres Superuser, Create role, Create DB, Replication {}
And the RDS one looks like:
Role Name Attr Member Of
<user> Create role, Create DB {rds_superuser}
rds_superuser Cannot login {}
rdsadmin ... ...
So it doesn't look like it's a permissions issue to me as <user> has superuser permissions in each case.
Solution for anyone looking:
I finally got this working using:
cat <db.sql> | sed -e '/^COMMENT ON EXTENSION plpgsql IS/d' > edited.dump
psql -h <RDS endpoint> -U <user> -e <dname> < edited.dump
It's not ideal for a reliable backup/restore mechanism but given it is only a comment I guess I can do without. My only other observation is that running psql/pg_restore to a remote host is slow. Hopefully the new database migration service will add something.
Considering your dumped DB file is of ~550MB, I think using the Amazon guide for doing this is the way out. I hope it helps.
Importing Data into PostgreSQL on Amazon RDS
I think it did not halt. It was just recreating indexes, foreign keys etc. Use pg_restore -v to see what's going on during the restore. Check the logs or redirect output to a file to check for any errors after import, as this is verbose.
Also I'd recommend using directory format (pg_dump -v -Fd) as it allows for parallel restore (pg_restore -v -j4).
You can ignore this ERROR: must be owner of extension plpgsql. This is only setting a comment on extension, which is installed by default anyway. This is caused by a peculiarity in RDS flavor of PostgreSQL, which does not allow to restore a database while connecting as postgres user.

How can I make new user in postgresql? [duplicate]

I have just installed postgresql and I specified password x during installation.
When I try to do createdb and specify any password I get the message:
createdb: could not connect to database postgres: FATAL: password authentication failed for user
Same for createuser.
How should I start?
Can I add myself as a user to the database?
The other answers were not completely satisfying to me. Here's what worked for postgresql-9.1 on Xubuntu 12.04.1 LTS.
Connect to the default database with user postgres:
sudo -u postgres psql template1
Set the password for user postgres, then exit psql (Ctrl-D):
ALTER USER postgres with encrypted password 'xxxxxxx';
Edit the pg_hba.conf file:
sudo vim /etc/postgresql/9.1/main/pg_hba.conf
and change "peer" to "md5" on the line concerning postgres:
local all postgres peer md5
To know what version of postgresql you are running, look for the version folder under /etc/postgresql. Also, you can use Nano or other editor instead of VIM.
Restart the database :
sudo /etc/init.d/postgresql restart
(Here you can check if it worked with psql -U postgres).
Create a user having the same name as you (to find it, you can type whoami):
sudo createuser -U postgres -d -e -E -l -P -r -s <my_name>
The options tell postgresql to create a user that can login, create databases, create new roles, is a superuser, and will have an encrypted password. The really important ones are -P -E, so that you're asked to type the password that will be encrypted, and -d so that you can do a createdb.
Beware of passwords: it will first ask you twice the new password (for the new user), repeated, and then once the postgres password (the one specified on step 2).
Again, edit the pg_hba.conf file (see step 3 above), and change "peer" to "md5" on the line concerning "all" other users:
local all all peer md5
Restart (like in step 4), and check that you can login without -U postgres:
psql template1
Note that if you do a mere psql, it will fail since it will try to connect you to a default database having the same name as you (i.e. whoami). template1 is the admin database that is here from the start.
Now createdb <dbname> should work.
Under Linux PostgresQL is usually configured to allow the root user to login as the postgres superuser postgres from the shell (console or ssh).
$ psql -U postgres
Then you would just create a new database as usual:
CREATE ROLE myuser LOGIN password 'secret';
CREATE DATABASE mydatabase ENCODING 'UTF8' OWNER myuser;
This should work without touching pg_hba.conf. If you want to be able to do this using some GUI tool over the network - then you would need to mess with pg_hba.conf.
There are two methods you can use. Both require creating a user and a database.
Using createuser and createdb,
$ sudo -u postgres createuser --superuser $USER
$ createdb mydatabase
$ psql -d mydatabase
Using the SQL administration commands, and connecting with a password over TCP
$ sudo -u postgres psql postgres
And, then in the psql shell
CREATE ROLE myuser LOGIN PASSWORD 'mypass';
CREATE DATABASE mydatabase WITH OWNER = myuser;
Then you can login,
$ psql -h localhost -d mydatabase -U myuser -p <port>
If you don't know the port, you can always get it by running the following, as the postgres user,
SHOW port;
Or,
$ grep "port =" /etc/postgresql/*/main/postgresql.conf
Sidenote: the postgres user
I suggest NOT modifying the postgres user.
It's normally locked from the OS. No one is supposed to "log in" to the operating system as postgres. You're supposed to have root to get to authenticate as postgres.
It's normally not password protected and delegates to the host operating system. This is a good thing. This normally means in order to log in as postgres which is the PostgreSQL equivalent of SQL Server's SA, you have to have write-access to the underlying data files. And, that means that you could normally wreck havoc anyway.
By keeping this disabled, you remove the risk of a brute force attack through a named super-user. Concealing and obscuring the name of the superuser has advantages.
This is my solution:
su root
su postgres
psql
EDIT: Warning: Please, read the answer posted by Evan Carroll. It seems that this solution is not safe and not recommended.
This worked for me in the standard Ubuntu 14.04 64 bits installation.
I followed the instructions, with small modifications, that I found in http://suite.opengeo.org/4.1/dataadmin/pgGettingStarted/firstconnect.html
Install postgreSQL (if not already in your machine):
sudo apt-get install postgresql
Run psql using the postgres user
sudo –u postgres psql postgres
Set a new password for the postgres user:
\password postgres
Exit psql
\q
Edit /etc/postgresql/9.3/main/pg_hba.conf and change:
#Database administrative login by Unix domain socket
local all postgres peer
To:
#Database administrative login by Unix domain socket
local all postgres md5
Restart postgreSQL:
sudo service postgresql restart
Create a new database
sudo –u postgres createdb mytestdb
Run psql with the postgres user again:
psql –U postgres –W
List the existing databases (your new database should be there now):
\l
In MacOS, I followed the below steps to make it work.
For the first time, after installation, get the username of the system.
$ cd ~
$ pwd
/Users/someuser
$ psql -d postgres -U someuser
Now that you have logged into the system, and you can create the DB.
postgres=# create database mydb;
CREATE DATABASE
postgres=# create user myuser with encrypted password 'pass123';
CREATE ROLE
postgres=# grant all privileges on database mydb to myuser;
GRANT
If you're running macOS like I am, you may not have the postgres user.
When trying to run sudo -u postgres psql I was getting the error sudo: unknown user: postgres
Luckily there are executables that postgres provides.
createuser -D /var/postgres/var-10-local --superuser --username=nick
createdb --owner=nick
Then I was able to access psql without issues.
psql
psql (10.2)
Type "help" for help.
nick=#
If you're creating a new postgres instance from scratch, here are the steps I took. I used a non-default port so I could run two instances.
mkdir /var/postgres/var-10-local
pg_ctl init -D /var/postgres/var-10-local
Then I edited /var/postgres/var-10-local/postgresql.conf with my preferred port, 5433.
/Applications/Postgres.app/Contents/Versions/10/bin/postgres -D /Users/nick/Library/Application\ Support/Postgres/var-10-local -p 5433
createuser -D /var/postgres/var-10-local --superuser --username=nick --port=5433
createdb --owner=nick --port=5433
Done!
Note: textdb is the database which you are going to explore with 'alex' user
root#kalilinux:~# sudo su - postgres
postgres=# psql
postgres=# create database testdb;
postgres=# create user alex with password 'alex';
postgres=# GRANT ALL PRIVILEGES ON DATABASE testdb TO alex;`enter code here`
You probably need to update your pg_hba.conf file. This file controls what users can log in from what IP addresses. I think that the postgres user is pretty locked-down by default.
Just browse up to your installation's directory and execute this file "pg_env.bat", so after go at bin folder and execute pgAdmin.exe. This must work no doubt!