<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Start Coding Now - misc</title><link href="https://startcodingnow.com/" rel="alternate"/><link href="https://startcodingnow.com/category/misc/feed" rel="self"/><id>https://startcodingnow.com/</id><updated>2020-07-15T00:00:00-07:00</updated><entry><title>How to Use psql in Docker Compose</title><link href="https://startcodingnow.com/psql-in-docker-compose" rel="alternate"/><published>2020-07-15T00:00:00-07:00</published><updated>2020-07-15T00:00:00-07:00</updated><author><name>Lance Goyke</name></author><id>tag:startcodingnow.com,2020-07-15:/psql-in-docker-compose</id><summary type="html">&lt;p class="first last"&gt;Get a grasp on these multiple environments&lt;/p&gt;
</summary><content type="html">&lt;p&gt;As a Django newbie, I’ve found it easy to consider the database stuff
“magic” and just leave it alone.&lt;/p&gt;
&lt;p&gt;I’m starting to realize, however reluctantly, that it’s super important
to know how databases work!&lt;/p&gt;
&lt;p&gt;After seeing a software engineer YouTuber talk through a few of his
database tables with some simple commands, I decided that would be a
helpful skill.&lt;/p&gt;
&lt;p&gt;So I ran &lt;tt class="docutils literal"&gt;psql&lt;/tt&gt; and then… obviously it didn’t work because &lt;strong&gt;that
would be too easy.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In this post, I’ll talk about how to use &lt;tt class="docutils literal"&gt;psql&lt;/tt&gt; to view your
PostgreSQL database from your Django project.&lt;/p&gt;
&lt;div class="section" id="the-docker-problem"&gt;
&lt;h2&gt;The Docker Problem&lt;/h2&gt;
&lt;p&gt;Docker has been great to me, but it’s also been a huge headache. There’s
just so much going on behind the scenes; it makes reality difficult to
comprehend. Layer that on top of learning Django and you’ve got a clear
path to overwhelm.&lt;/p&gt;
&lt;p&gt;For context, I can attribute my knowledge of Docker and Docker Compose
to Will Vincent from his book “Django for Professionals”. That book
really helped getting going, but deviating from that path is definitely
challenging.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="how-to-run-the-django-server-locally"&gt;
&lt;h2&gt;How to Run the Django Server Locally&lt;/h2&gt;
&lt;p&gt;Here’s a quick review of my local setup.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dockerfile&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="literal-block"&gt;
# pull base image
FROM python:3.8

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# set work directory
WORKDIR /code

# install dependenceies
COPY Pipfile Pipfile.lock /code/
RUN pip install pipenv &amp;amp;&amp;amp; pipenv install --system

# copy project
COPY . /code/
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;docker-compose.yml&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="literal-block"&gt;
version: "3.7"

services:
  web:
    build: .
    command: python /code/manage.py runserver 0.0.0.0:8000
    env_file:
      - .env
    volumes:
      - .:/code
    ports:
      - 8000:8000
    depends_on:
      - db
  db:
    image: postgres:12
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      - "POSTGRES_HOST_AUTH_METHOD=trust"
    env_file:
      - .env
    ports:
      - 5432:5432

volumes:
  postgres_data:
&lt;/pre&gt;
&lt;p&gt;Then to run the local Django server and local PostgreSQL database:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo docker-compose up -d --build
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="accessing-the-python-container"&gt;
&lt;h2&gt;Accessing the Python Container&lt;/h2&gt;
&lt;p&gt;When running management commands with Docker Compose, we have to specify
which service we want to run the command.&lt;/p&gt;
&lt;p&gt;I have two services: &lt;strong&gt;web&lt;/strong&gt; and &lt;strong&gt;db&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;When I need to use Django’s &lt;tt class="docutils literal"&gt;manage.py&lt;/tt&gt;, I have to prepend this
command:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo docker-compose exec web...
&lt;/pre&gt;
&lt;p&gt;So, for example, when I want to migrate my users app migrations, it
looks like this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo docker-compose exec web python manage.py migrate users
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="python-container-or-database-container"&gt;
&lt;h2&gt;Python Container or Database Container?&lt;/h2&gt;
&lt;p&gt;So there are two ways (that I know) to access the &lt;tt class="docutils literal"&gt;psql&lt;/tt&gt; command.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;python manage.py dbshell&lt;/li&gt;
&lt;li&gt;psql&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="section" id="python-manage-py-dbshell"&gt;
&lt;h3&gt;python manage.py dbshell&lt;/h3&gt;
&lt;p&gt;As specified in the &lt;a class="reference external" href="https://docs.djangoproject.com/en/3.0/ref/django-admin/#dbshell"&gt;Django
docs&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;dbshell&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Runs the command-line client for the database engine specified in
your &lt;a class="reference external" href="https://docs.djangoproject.com/en/3.0/ref/settings/#std:setting-DATABASE-ENGINE"&gt;ENGINE&lt;/a&gt;
setting, with the connection parameters specified in
your &lt;a class="reference external" href="https://docs.djangoproject.com/en/3.0/ref/settings/#std:setting-USER"&gt;USER&lt;/a&gt;, &lt;a class="reference external" href="https://docs.djangoproject.com/en/3.0/ref/settings/#std:setting-PASSWORD"&gt;PASSWORD&lt;/a&gt;,
etc., settings.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;For PostgreSQL, this runs the &lt;strong&gt;psql&lt;/strong&gt; command-line client.&lt;/li&gt;
&lt;li&gt;For MySQL, this runs the &lt;strong&gt;mysql&lt;/strong&gt; command-line client.&lt;/li&gt;
&lt;li&gt;For SQLite, this runs the &lt;strong&gt;sqlite3&lt;/strong&gt; command-line client.&lt;/li&gt;
&lt;li&gt;For Oracle, this runs the &lt;strong&gt;sqlplus&lt;/strong&gt; command-line client.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This sounds like the way to go, so let’s run it.&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo docker-compose exec web python manage.py dbshell
&lt;/pre&gt;
&lt;p&gt;And then we get an error:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
CommandError: You appear not to have the 'psql' program installed or on your path.
&lt;/pre&gt;
&lt;p&gt;WHAT!? How is that possible?&lt;/p&gt;
&lt;p&gt;Our PostgreSQL service “db” surely has &lt;tt class="docutils literal"&gt;psql&lt;/tt&gt; installed, but that’s a
different container. Instead of trying to install &lt;tt class="docutils literal"&gt;psql&lt;/tt&gt; inside our
“web” container, let’s try running &lt;tt class="docutils literal"&gt;psql&lt;/tt&gt; directly from the “db”
service.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="psql"&gt;
&lt;h3&gt;psql&lt;/h3&gt;
&lt;p&gt;To run, we’ll have to specify the “db” service:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo docker-compose exec db psql
&lt;/pre&gt;
&lt;p&gt;Annnnnnd we get another error:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
psql: error: could not connect to server: FATAL:  role "root" does not exist
&lt;/pre&gt;
&lt;p&gt;This error is telling us that &lt;tt class="docutils literal"&gt;psql&lt;/tt&gt; is, in fact, available. Confirm
by checking the version.&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo docker-compose exec db psql --version
&lt;/pre&gt;
&lt;p&gt;Now the error told us that “role ‘root’ does not exist”. The default
command with no arguments is trying to log in as root. But if we check
out the &lt;tt class="docutils literal"&gt;.env&lt;/tt&gt; file, we can see we specified different values for the
PostgreSQL database name, username, and password:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
POSTGRES_DB=postgres
POSTGRES_USER=postgres
POSTGRES_PASSWORD=supersecretpassword
POSTGRES_HOST=db
POSTGRES_PORT=5432
&lt;/pre&gt;
&lt;p&gt;Well hey then, we don’t NEED to connect from “root”. What if we specify
the username with the -U flag?&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo docker-compose exec db psql -U postgres
&lt;/pre&gt;
&lt;p&gt;Then we get a new prompt:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
postgres=#
&lt;/pre&gt;
&lt;p&gt;This is the &lt;tt class="docutils literal"&gt;psql&lt;/tt&gt; prompt.&lt;/p&gt;
&lt;p&gt;If you’re still getting an error:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
psql: error: FATAL:  database "postgres" does not exist
&lt;/pre&gt;
&lt;p&gt;It’s because psql is trying to login to the database “postgres” as the
user “postgres”, but your database and user are different. You can
specify them both with the -d and -U flags:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo docker-compose exec db psql -d postgres_db -U postgres_username
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="next-steps"&gt;
&lt;h2&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;Hey congrats! Now you can use psql!&lt;/p&gt;
&lt;p&gt;Or should I say, “Now you have to learn psql commands!”&lt;/p&gt;
&lt;p&gt;Here’s a few to get your started:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;List all databases: &lt;tt class="docutils literal"&gt;\l&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;View all tables in the current database: &lt;tt class="docutils literal"&gt;\d&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Describe a table: &lt;tt class="docutils literal"&gt;\d table_name&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;List all available users: &lt;tt class="docutils literal"&gt;\du&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Quit psql: &lt;tt class="docutils literal"&gt;\q&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="misc"/></entry></feed>