Сводка в одну строку: Я бы хотел 1) Раскрутить базу данных Postgres, которая запускается в Docker 2) Заполнить эту базу данных PostgreSQL фреймом данных Pandas, используя SQLAlchemy извне контейнера .
Docker работает нормально:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
27add831cce5 postgres:10.1-alpine "docker-entrypoint.s…" 2 weeks ago Up 2 weeks 5432/tcp django-postgres_db_1
Мне удалось найти сообщения о получении фрейма данных pandas в Postgres и использовании SQLAlchemy для создания таблицы в Dockerized Postgres.,Соединяя это вместе, я получаю следующее, что (вроде) работает:
import numpy as np
import pandas as pd
from sqlalchemy import create_engine
from sklearn.datasets import load_iris
def get_iris():
iris = load_iris()
return pd.DataFrame(data=np.c_[iris['data'], iris['target']],
columns=iris['feature_names'] + ['target'])
df = get_iris()
print(df.head(n=5))
engine = create_engine(
'postgresql://postgres:mysecretpassword@localhost:5432/postgres'.format(
'django-postgres_db_1'))
df.to_sql('iris', engine)
Вопросы :
q.1 )Вышеупомянутое близко к предпочтительному способу сделать это?
q.2 ) Есть ли способ создать дБ в Postgres, используя SQLAlchemy?Например, мне не нужно вручную добавлять новый БД или заполнять стандартный Postgres.
Проблемы :
стр.1 ) Когда я запускаю create_engine
, который «работает», я получаю следующую ошибку:
File "/home/tmo/projects/toy-pipeline/venv/lib/python3.5/site-packages/sqlalchemy/dialects/postgresql/psycopg2.py", line 683, in do_executemany
cursor.executemany(statement, parameters)
KeyError: 'sepal length (cm'
Однако, если я снова запускаю код, он говорит, что таблица радужной оболочки уже существует.Если я обращаюсь к базе данных Postgres вручную и выполняю postgres=# TABLE iris
, она ничего не возвращает.
стр.2 ) У меня есть таблица в моей базе данных Postgres, работающей в Docker, которая называется testdb
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+------------+------------+-----------------------
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
testdb | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
(4 rows)
, но если я попытаюсь вставить эту таблицу вcreate_engine
Я получаю сообщение об ошибке:
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) FATAL: database "testdb" does not exist
(обратите внимание, как postgres
был заменен на testdb
):
engine = create_engine(
'postgresql://postgres:mysecretpassword@localhost:5432/testdb'.format(
'django-postgres_db_1'))
Обновление :
Итак, я думаю, я выяснил, в чем может быть проблема: неправильное использование имени хоста и адреса.Я должен упомянуть, что я работаю на экземпляре Azure в Ubuntu 16.04.
Вот некоторая полезная информация о контейнере, на котором выполняется Postgres:
HOSTNAME=96402054abb3
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/postgresql/10/bin
PGDATA=/var/lib/postgresql/data
PG_MAJOR=10
PG_VERSION=10.5-1.pgdg90+1
И о etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 96402054abb3
Как мне сконструировать мойСтрока подключения правильно? Я пробовал:
Имя контейнера, как предлагается здесь :
engine = create_engine(
'postgresql://postgres:saibot@{}:5432/testdb'.format(
'c101519547f8e89c3422ca9e1dc68d85ad9f24bd8e049efb37273782540646f0'))
OperationalError: (psycopg2.OperationalError) could not translate host name "96402054abb3" to address: Name or service not known
, и я попытался вставить ip, localhost
, HOSTNAME
и т. Д. Без удачи.
Я использую этот фрагмент кода, чтобы проверить, подключается ли БД:
from sqlalchemy import create_engine
from sqlalchemy_utils import database_exists
engine = create_engine(
'postgresql://postgres:saibot@172.17.0.2/testdb')
database_exists(engine.url)