Как подключиться к PostgreSQL, работающему в Docker-контейнере, из локального R?

У меня есть локальный контейнер Docker под управлением PostgreSQL. Я хочу иметь возможность подключаться и взаимодействовать с этой базой данных из R, запущенной на моем хост-компьютере (Mac OS).

Я могу подключиться с помощью pgadmin4 по следующему адресу

http://0.0.0.0:5434/browser/

затем добавляем новый сервер:

Добавить новый сервер. Вкладка "Общие" -> name: tagbase. Вкладка "Соединение" -> Имя хоста / адрес: postgres. Вкладка "Соединение" -> Порт: 5432. Вкладка "Соединение" -> База данных обслуживания: postgres. Вкладка "Соединение" -> Имя пользователя: база тегов

Это работает отлично.

Однако для подключения из R I попробуйте:

require("RPostgreSQL")

# load the PostgreSQL driver
drv <- dbDriver("PostgreSQL")

# create a connection to the postgres database
con <- RPostgreSQL::dbConnect(drv, dbname = "postgres",
                 host = "localhost", port = 5434,
                 user = "tagbase", password = "tagbase")

Эта попытка просто зависает, пока не произойдет сбой R.

Возможно, жизнеспособное решение является чем-то похожим на это. Большое спасибо за любую помощь.


РЕДАКТИРОВАТЬ - 20190207

Спасибо за комментарии. Я внес изменения без каких-либо улучшений, но согласился, что изменения необходимы.

Я успешно запускаю эту сеть докеров (из 3 контейнеров) через терминал, как показано ниже. Мне кажется, что я хочу подключиться к контейнеру postgres на 0.0.0.0 через порт 5432, правильно?

$ docker-compose up
Starting tagbase-server_postgres_1_3f42d4fc1a77 ... done
Starting tagbase-server_pgadmin4_1_52ab92a49f22 ... done
Starting tagbase-server_tagbase_1_9d3a22c8be46  ... done
Attaching to tagbase-server_postgres_1_3f42d4fc1a77, tagbase-server_pgadmin4_1_52ab92a49f22, tagbase-server_tagbase_1_9d3a22c8be46
postgres_1_3f42d4fc1a77 | 2019-02-05 19:35:45.999 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432

Я думал, что я подключался к серверу через R точно так же, как я использовал pgadmin, но следующее не работает:

# create a connection to the postgres database
con <- DBI::dbConnect(RPostgreSQL::PostgreSQL(), dbname = "postgres",
                  host = "0.0.0.0", port = 5432,
                  user = "tagbase", password = "tagbase")

Error in postgresqlNewConnection(drv, ...) : 
RS-DBI driver: (could not connect tagbase@0.0.0.0:5432 on dbname "postgres": 
FATAL:  role "tagbase" does not exist)

Теперь я понимаю, что pgadmin также работает в сети контейнера докеров. Таким образом, локальный хост для соединения pgadmin является сервером базы данных. Похоже, мне нужно такое решение

Обратите внимание, что источник для сборок Docker находится здесь, следуя инструкциям здесь.

0 ответов

Если вы хотите напрямую подключиться к базе данных postgres внутри докера из внешнего мира докеров, вы должны открыть порт в докере postgres. Итак, сначала вам нужно отредактировать файл "Dockerfile-postgres" и добавить EXPOSE 5432

FROM postgres:10

COPY ./sqldb/tagbase-schema.sql /docker-entrypoint-initdb.d/
# Expose default postgres port
EXPOSE 5432

Затем соберите и запустите докеры в соответствии с предоставленными инструкциями (проверено 6 октября 2019 г.)

$ docker-compose build
$ docker-compose up

Добавьте базу данных с помощью pgAdmin

Добавить новый сервер  Вкладка "Общие" -> name: tagbase  Вкладка "Соединение" -> Имя / адрес хоста: postgres  Вкладка "Соединение" -> Порт: 5432  Вкладка "Соединение" -> База данных обслуживания: postgres  Вкладка "Соединение" -> Имя пользователя: tagbase

Отредактируйте сценарий R в соответствии с именем и портом базы данных:

# install.packages('RPostgreSQL')
library(RPostgreSQL)

# load the PostgreSQL driver
drv <- dbDriver("PostgreSQL")

# create a connection to the postgres database
con <- RPostgreSQL::dbConnect(drv, dbname = "tagbase",
                              host = "localhost", port = 5432,
                              user = "tagbase", password = "tagbase")

# Test query
temp <- dbGetQuery(con, 'select * from public.metadata_types')

# Evaluate output
str(temp)
# 'data.frame': 142 obs. of  8 variables:
#   $ attribute_id  : num  1 2 3 4 5 6 7 8 9 10 ...
# $ category      : chr  "instrument" "instrument" "instrument" "instrument" ...
# $ attribute_name: chr  "instrument_name" "instrument_type" "firmware" "manufacturer" ...
# $ type          : chr  "string" "string" "string" "string" ...
# $ description   : chr  "Append an identifer that is unique within your organization. This is essential if a device is recycled." "Type of instrument" "Version number of the firmware used to build the device" "Name of manufacturer" ...
# $ example       : chr  "16P0100-Refurb2" "archival, popup, satellite, acoustic tag, or acoustic receiver" NA "Wildlife Computers, Microwave Telemetry, Lotek Wireless, Desert Star Systems, CEFAS, StarOddi, Sea Mammal Resea"| __truncated__ ...
# $ comments      : chr  "Devices might be reused, so the serial number will be the same. The only way to distinguish is by providing a u"| __truncated__ "Should be restricted to the examples provided." NA NA ...
# $ necessity     : chr  "required" "required" "required" "required" ...

# Disconnect from database
dbDisconnect(con)
Другие вопросы по тегам