How do I run a sql file of inserts through docker run?
Asked Answered
M

5

67

Given a file with a SQL insert:

INSERT INTO countries (id, country_code, name)
VALUES
    (1, 'AF', 'Afghanistan'),
    (2, 'AL', 'Albania');

I would like to run the file by using the docker run command on a container that is running postgres.

I've tried this:

docker run -e domain="192.168.99.100" pg /bin/bash -c "psql -d whiteboard_api -a -f inserts_into_countries_table.sql"
psql: could not connect to server: Connection refused
    Is the server running locally and accepting
    connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?

you can see my image is pg:

capistrano:whiteboard_v2 jzollars$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
6b500bec9210        bbb                 "/usr/bin/supervisord"   4 weeks ago         Up 4 weeks          0.0.0.0:80->80/tcp       distracted_raman
c1e88f2695f5        wh                  "/usr/bin/supervisord"   4 weeks ago         Up 4 weeks          0.0.0.0:3000->3000/tcp   high_einstein
7e383e99bdc3        pg                  "/usr/lib/postgresql/"   4 weeks ago         Up 4 weeks          0.0.0.0:5432->5432/tcp   pg_test

How can I load this file and run it in a docker container using docker run?

Matriculate answered 9/1, 2016 at 0:49 Comment(1)
could you share your pg image Dockerfile?Hevesy
S
105

to execute commands against a running container use docker exec.

to copy a file (ex: dump.sql) into a container, use docker cp

So your approach might look something like this:

docker cp ./dump.sql pg_test:/docker-entrypoint-initdb.d/dump.sql
docker exec -u postgres pg_test psql postgres postgres -f docker-entrypoint-initdb.d/dump.sql

here it is in generic form:

docker cp ./localfile.sql containername:/container/path/file.sql
docker exec -u postgresuser containername psql dbname postgresuser -f /container/path/file.sql

And note that if you need to seed your database every time it is run, the folder /docker-entrypoint-initdb.d/ does have special significance, if you're using the offical postgres image

Standush answered 9/1, 2016 at 2:14 Comment(4)
Thanks this was a great answer, especially like the "generic form"Matriculate
is there away to do this without copying the file into the container?Evacuee
I did some looking round and I couldn't find anyway to do it without copying the file into the docker container, if anyone finds a way please post the answerEvacuee
@MaxCarroll, you can mount your file into the container, rather than explicitely copying it, using the volume flag: docker run -v ./dump.sql:/docker-entrypoint-initdb.d/dump.sql pg_testStandush
A
97

You can run a sql command file against a running postgres container via the one liner

cat ./query.sql | docker exec -i <container-name> psql -U <user> -d <database>

without having to copy the file from your host machine to the container.

Angus answered 18/5, 2020 at 21:43 Comment(4)
This worked for me. I was hesitant to use the other answers since they all use multiple lines or would store the file on the docker instance. I think this is the best answer for my use case since it just executes the script and nothing else.Williamsen
Based on this answer I expected this to work as well, and it did. Thanks. echo SELECT * FROM table; | docker exec -i postgresdb psql -U user -d dbComehither
Seems to work only when psql is run on the db in the docker container. Won't run on a "remote" db. Mentioned this because I only want to use the psql command of the docker container to run an SQL on another db.Narvik
Ok. Figured out how to do it: echo "select count(*) from ..." | docker exec -i postgres-12.3 sh -c "export PGPASSWORD=<pwd> && psql -U <user> -h <ip> -p 5432 -d <db>" Thanks for the answer. It helped.Narvik
S
9

With the official Docker image of PostgreSQL, code_monk's answer does not work for me. I arrive to this solution:

docker exec -it <container-name> psql -U <DB_USER> -d <DB_NAME> -f /file.sql
Sevenup answered 9/11, 2018 at 7:32 Comment(2)
is the /file.sql inside the container or is it on the host, i tried this but it says file not found im wondering if its looking for the file in the container instead of the host?Evacuee
The file must be in the container. You can copy it with docker cpSevenup
H
1
#!/bin/bash
set -e

FUN_SQL2="
CREATE OR REPLACE FUNCTION insert_event(text)
  RETURNS integer AS
\\\\$BODY\\\\$
DECLARE ret INTEGER;
begin
select $1 into ret;
RETURN ret;

end;
\\\\$BODY\\\\$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;
"

# add function to DB
docker exec -it db_container sh -c "psql -U postgres -d db_name -c \"$FUN_SQL2\" ";
Haydon answered 12/3, 2020 at 6:52 Comment(1)
\\\$BODY\\\ must contain 3 \\\Haydon
S
1

Just in case, if you also want to ssh, here is one liner with script/sql

#!/bin/bash

ssh -tt -i .ssh/local.pem username@remotehost docker exec -ti docker-container /usr/bin/psql postgresql://user:password@dbhost:port/dbname -f sqlscript_on_docker

ssh -tt -i .ssh/local.pem username@remotehost docker exec -ti docker-container /usr/bin/psql postgresql://user:password@dbhost:port/dbname -c \"select \* from table\”

Shanta answered 13/1, 2023 at 18:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.