Не получается установить соединение с базой данных postgres в asyncpg
Есть вот такой код создания бд
async def create_db():
create_db_command = open("create_db.sql").read()
logging.info("Connecting to database...")
conn: asyncpg.Connection = await asyncpg.connect(user=PG_USER,
password=PG_PASS,
host=host)
await conn.execute(create_db_command)
await conn.close()
logging.info("Table users created")
async def create_pool():
return await asyncpg.create_pool(user=PG_USER,
password=PG_PASS,
host=host)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(create_db())
Переменные PG_USER, PG_PASS и host инициализируются с помощью переменных окружения, задающихся в файле.env
PGHOST=db
PG_USER=postgres
PG_PASS=123456
Я использую операционную систему ubuntu, постгрес работает в контейнере докера. Контейнер запускаю с помощью файла yml
version: '3.1'
services:
db:
image: postgres
restart: always
environment:
POSTGRES_PASSWORD: 123456
adminer:
image: adminer
restart: always
ports:
- 6080:8080
Чтоб зайти в постгрес через админ я ввожу логин postgres, пороль 123456 и сервер db, но при попытке коннектиться к db через скрипт питона возникает ошибка, связанная с хостом.(ниже то, что выводится в терминал)
sql.py [LINE:14] #INFO [2020-08-15 01:58:31,909] Connecting to database... Traceback (most recent call last): File "/home/anton/dev/Bots/EnglishGitBot/sql.py", line 31, in loop.run_until_complete(create_db()) File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete return future.result() File "/home/anton/dev/Bots/EnglishGitBot/sql.py", line 15, in create_db conn: asyncpg.Connection = await asyncpg.connect(user=PG_USER, File "/home/anton/.local/lib/python3.8/site-packages/asyncpg/connection.py", line 1718, in connect return await connect_utils._connect( File "/home/anton/.local/lib/python3.8/site-packages/asyncpg/connect_utils.py", line 674, in _connect raise last_error File "/home/anton/.local/lib/python3.8/site-packages/asyncpg/connect_utils.py", line 663, in _connect con = await _connect_addr( File "/home/anton/.local/lib/python3.8/site-packages/asyncpg/connect_utils.py", line 632, in _connect_addr tr, pr = await asyncio.wait_for( File "/usr/lib/python3.8/asyncio/tasks.py", line 483, in wait_for return fut.result() File "/usr/lib/python3.8/asyncio/base_events.py", line 986, in create_connection infos = await self._ensure_resolved( File "/usr/lib/python3.8/asyncio/base_events.py", line 1365, in _ensure_resolved return await loop.getaddrinfo(host, port, family=family, type=type, File "/usr/lib/python3.8/asyncio/base_events.py", line 825, in getaddrinfo return await self.run_in_executor( File "/usr/lib/python3.8/concurrent/futures/thread.py", line 57, in run result = self.fn(*self.args, **self.kwargs) File "/usr/lib/python3.8/socket.py", line 918, in getaddrinfo for res in _socket.getaddrinfo(host, port, family, type, proto, flags): socket.gaierror: [Errno -3] Temporary failure in name resolution
Какое значение должно быть у хоста, чтоб соединение установилось? я пробовал вбивать ip докер контейнера, в котором запущен bd и локальный адрес.
Ответы (2 шт):
Измените ваш докер композ файл, добавив туда линковку порта докер контейнера с базой на хостовую систему
version: '3.1'
services:
db:
image: postgres
restart: always
environment:
POSTGRES_PASSWORD: 123456
ports:
- "127.0.0.1:5432:5432"
adminer:
image: adminer
restart: always
ports:
- 6080:8080
После этого требуется перезапустить командами
docker-compose stop
docker-compose up -d
Чтобы поднятые контейнеры перечитали композ файл. Теперь можно запускать код указав в качестве хоста для подключения к БД 127.0.0.1, а в качестве порта 5432 (по умолчанию для постгреса)
Вам нужно сделать так чтоб контейнеры друг друга видели. Как это сделать ? Раньше это делалось с помощью link Если вы уже зашли по ссылке то увидели что это уже давно старо и использовать это не нужно. Как же сделать так чтоб контейнеры друг друга видели ? Очевидно что через network. Можно начать читать отсюда
Теперь в остатке. Как вам через Compose сделать видимыми друг другу контейнеры. Я прям сейчас не уверен, ибо у меня описаны в compose всё что я хочу описать, однако мне думается что по-умолчанию можно не описывать сеть для ваших сервисов и достаточно просто будет указать hostname в вашем сервисе db
Можете посмотреть все о чем я говорил на этом примере