DjangoGirls / tutorial-extensions

Additional tasks for tutorial
https://tutorial-extensions.djangogirls.org
Other
163 stars 203 forks source link

Can't access postgres shell #59

Closed muroshi closed 7 years ago

muroshi commented 7 years ago

Hi if I write:

$ psql

As recommended into your postgres tutorial. This will yield:

psql: FATAL: database "username" does not exist

While username is the linux ubuntu username. Can you write how to get around this?

helenst commented 7 years ago

Hi @muroshi

psql is looking for a database with the same name as your user but it probably doesn't exist (and we don't really want it to either).

We can get around this by running postgres as a different user. There's a special user called postgres that is the default database user - when you run psql as postgres it doesn't look for any databases, it just starts.

You can try switching to the postgres user like this

$ sudo -i -u postgres

You'll need to type in your linux password.

Then your command prompt should look like this:

postgres@your-computer-name $

That means everything you run on that command line will be done as the postgres user. You should now be able to run psql and create the user and database as shown in the tutorial. When you are finished in psql you can type exit to become your regular user again.

I hope that works for you - I don't have a fresh postgres install right now to check this on. Let us know how it goes and we can update the tutorial if it is the right fix! :sparkles:

muroshi commented 7 years ago

Hello @helenst

Thank you. It should have worked to create the user and db. As soon as I want to connect to that db through the provided migrate command I receive:

django.db.utils.OperationalError: fe_sendauth: no password supplied.

Don't we have to start the db-server?

helenst commented 7 years ago

Hi @muroshi It sounds as if the database server is running, but there is still something not right with the authentication. I think this will need somebody to try this with a clean postgresql setup to see what steps need to be taken.

Can you tell us which version of Ubuntu you are running please? And which postgresql version (You can type in psql --version to find that out).

muroshi commented 7 years ago

Hi @helenst I'm using Ubuntu LTS 16.04 and psql (PostgreSQL) 9.5.5 (fresh install). I'm not sure if it's running (I don't see a user postgres under my user accounts.

Cheers

helenst commented 7 years ago

Hi @muroshi

You probably won't see postgres listed alongside regular users. It's a special system account so won't be listed with the regular user ones. If you were able to run the sudo command in my previous comment, that account definitely exists - and if you were able to open psql and interact with it (create the user and database etc) that means the server is running.

If you want to check that, you can type in:

service postgresql status

I think the problem is that Postgres won't authenticate a user with no password, unless that user matches a Unix user. So let's try using your Ubuntu username for this.

Go back into the postgres user and run psql

$ sudo -i -u postgres
$ psql

We're going to create a database user that matches your ubuntu user, and give them ownership of the djangogirls database. Since it is a new database with nothing in it, the easiest thing is to remove the old one and recreate it with the right owner.

On the psql prompt, type the following lines, replacing the your-ubuntu-username placeholders (including angle brackets) with your Ubuntu username.

CREATE USER your-ubuntu-username
DROP DATABASE djangogirls
CREATE DATABASE djangogirls OWNER your-ubuntu-username

Type \q to quit psql and then exit() to get out of the postgres user and back to your regular user.

Update DATABASES in mysite/settings.py to the following, replacing the placeholder with your ubuntu username:

'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'djangogirls',
        'USER': 'your-ubuntu-username',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
    }

So HOST is now an empty string, and it's connecting with your ubuntu username. You still don't need a password, but since you will be running manage.py as your ubuntu user, Postgres will use that to authenticate you and give you access to the database.

I hope that makes sense, and that it works this time. :sunglasses:

(I think it's hard to write Postgres instructions that work easily for everybody, since there are various different ways to authenticate and it seems to vary across platforms - hopefully we can use this to make things better!)

muroshi commented 7 years ago

Hi @helenst Thanks a lot. This solution works for my Local Ubuntu. But I'm using a laptop too, it comes with another user name. Do you know how we could make it that it still works without needing to alter settings.py?

What's the reason of the 'localhost' removal under HOST?

Cheers

helenst commented 7 years ago

Hi @muroshi

When you tell it to use localhost it tells Postgres that you're connecting as a network user and Postgres starts to expect different kinds of authentication. An empty HOST value means it's a truly local connection and you can be a unix user.

If you are using it on multiple machines, there a couple of options.

You can either:

  1. Get Django to use different versions of settings.py. It's best to keep the original settings.py and import it from your custom version. So you get the original values and then you can override the username.

e.g. you could have laptop_settings.py in the same directory as settings.py which looks like this:

from settings import *

DATABASES['default']['username'] = 'my-laptop-username'

And you can run it like this:

$ python manage.py runserver --django-settings-module=mysite.laptop_settings

OR:

  1. Set up the database as suggested by the tutorial (owned by the non-unix user "name") but when you create the user, give it a password.
CREATE USER name WITH PASSWORD 'djangogirls'

or if you already created the user:

ALTER USER name WITH PASSWORD 'djangogirls'

Then add the password into the settings like this:

'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'djangogirls',
        'USER': 'name',
        'PASSWORD': 'djangogirls',
        'HOST': 'localhost',
        'PORT': '',
    }

Note that we've gone back to using localhost since it's not a unix user.

Note also that this means putting a password into your code. This is OK in this case because you're learning and experimenting and running on your local machines (and PostgreSQL is set up so people can't just connect to it over a network, even if they do know your password). But since it's going into source code (which you might push publicly to GitHub) you should use a throwaway password and not something important or that you would use elsewhere.

If you want to do this on a production setup, you should manage the password more carefully. There are ways that you can avoid storing the password in code but that's probably more involved than I need to get here! (There is a good guide to this and many other things in the Two Scoops of Django book if you are interested)

I hope that's clear! I'm not sure which is the best way to handle this in the tutorial but would be interested to know your thoughts.

muroshi commented 7 years ago

Hi @helenst - YAY trailrunning!

I guess the first way could become handy if I later have a heroku settings. However, with

$ python manage.py runserver --django-settings-module=mysite.laptop_settings

I receive an error: unrecognized arguments: --django-settings-module=mysite.laptop_settings

The file looks like:

from settings import *

DATABASES['default']['USER'] = 'my-laptop-username'

As long as I'm not on heroku the localhost version might be more comfortable, because I don't have to remember and type an additional parameter and path.

helenst commented 7 years ago

Apologies! I should have looked that up before I typed it. It should be

--settings=mysite.laptop_settings

There's an alternative, where you can set the DJANGO_SETTINGS_MODULE environment variable (See https://docs.djangoproject.com/en/1.10/ref/django-admin/#cmdoption--settings) - I must have confused it with that.

Trail running is the best running! :running_woman:

muroshi commented 7 years ago

Hello again, @helenst , turns out that I had to use from .settings import * and to use--settings=mysite.laptop_settings.py' as a parameter if you want to add this trick to your tutorial.

Can you go into authentication with allauth? (their docu is not very beginner friendly at all.)

Best wishes

muroshi commented 7 years ago

Thanks a lot, Mrs @helenst.

helenst commented 7 years ago

You're welcome. allauth authentication could be a nice tutorial extension - you could open an issue to suggest it! I am going to close this one - we've now got another issue open for improving the Postgres extension, based on your very useful input. Thank you for helping to make the tutorial better! :tulip::purple_heart: