#python #mysql #docker #docker-compose #mysql-python
Вопрос:
Я пытаюсь вместить скрипт Python и базу данных MySQL с помощью Docker. Скрипт python взаимодействует с программой, запущенной на хост-машине, используя TCP-соединение, поэтому я настроил сеть «хост» для контейнеров Docker, чтобы разрешить это. Скрипт python в настоящее время нормально разговаривает с программой на хост-машине (TCP-связь, как и ожидалось). Скрипт python также взаимодействует с базой данных MySQL, работающей в другом контейнере, нормально (никаких ошибок со стороны pymysql). Когда я использую интерфейс Docker Desktop CLI, я вижу временные метки в файлах в /var/lib/mysql/donuts/*.ibd
контейнере базы данных, обновляющихся по мере того, как код python вводит информацию в таблицы.
Однако моя проблема заключается в том, что, когда я опускаю оба контейнера docker compose down
, а затем снова поднимаю их docker compose up
, информация в базе данных не сохраняется. На самом деле, если я войду в контейнер базы данных с помощью интерфейса командной mysql -u donuts
строки, а затем попытаюсь вручную проверить таблицы во время работы контейнеров, обе таблицы будут полностью пустыми. Я ходил по кругу, пытаясь выяснить, почему я не могу видеть данные в таблицах, хотя вижу файлы в /var/lib/mysql/donuts/*.ibd
обновлении в том же экземпляре, в который контейнер Python вставляет строки. Данные хранятся где-то во время работы контейнеров, по крайней мере временно, так как контейнер python считывает данные из одной из таблиц и использует эту информацию, пока контейнеры живы.
Ниже приведены мои Dockerfile
файлы и docker-compose.yml
файлы, и весь проект можно найти здесь. Код python, который взаимодействует с базой данных, находится здесь, но я думаю, что проблема должна быть в настройке Docker, а не в коде Python.
Любые советы по сохранению базы данных были бы очень признательны, спасибо.
version: '3.1'
services:
db:
image: mysql:8.0.25
container_name: db
restart: always
secrets:
- mysql_root
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mysql_root
MYSQL_DATABASE: donuts
volumes:
- mysql-data:/var/lib/mysql
- ./mysql-init.sql:/docker-entrypoint-initdb.d/mysql-init.sql
network_mode: "host"
voyager_donuts:
container_name: voyager_donuts
build:
context: .
dockerfile: Dockerfile
image: voyager_donuts
network_mode: "host"
volumes:
- c:/Users/user/Documents/Voyager/DonutsCalibration:/voyager_calibration
- c:/Users/user/Documents/Voyager/DonutsLog:/voyager_log
- c:/Users/user/Documents/Voyager/DonutsData:/voyager_data
- c:/Users/user/Documents/Voyager/DonutsReference:/voyager_reference
volumes:
mysql-data:
secrets:
mysql_root:
file: ./secrets/mysql_root
# get a basic python image
FROM python:3.9-slim-buster
# set up Tini to hand zombie processes etc
ENV TINI_VERSION="v0.19.0"
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod x /tini
# keep setup tools up to date
RUN pip install -U
pip
setuptools
wheel
# set a working directory
WORKDIR /donuts
# make a new user
RUN useradd -m -r donuts amp;amp;
chown donuts /donuts
# install requirements first to help with caching
COPY requirements.txt ./
RUN pip install -r requirements.txt
# copy from current dir to workdir
COPY . .
# stop things running as root
USER donuts
# add entry points
ENTRYPOINT ["/tini", "--"]
# start the code once the container is running
CMD python voyager_donuts.py
Ответ №1:
И, конечно, как только я опубликую это, я найду ответ. В моем диспетчере контекста подключения к базе данных отсутствовала commit()
строка. Ле вздох, я потратил гораздо больше времени, чем хотел бы признать, на то, чтобы разобраться в этом…
@contextmanager
def db_cursor(host='127.0.0.1', port=3306, user='donuts',
password='', db='donuts'):
"""
Grab a database cursor
"""
with pymysql.connect(host=host,
port=port,
user=user,
password=password,
db=db) as conn:
with conn.cursor() as cur:
yield cur
должно было быть:
@contextmanager
def db_cursor(host='127.0.0.1', port=3306, user='donuts',
password='', db='donuts'):
"""
Grab a database cursor
"""
with pymysql.connect(host=host,
port=port,
user=user,
password=password,
db=db) as conn:
with conn.cursor() as cur:
yield cur
conn.commit()