【问题标题】:Persisting mysql database with docker使用 docker 持久化 mysql 数据库
【发布时间】:2021-06-07 18:03:22
【问题描述】:

我正在尝试使用 Docker 将 Python 脚本和 MySQL 数据库容器化。 python 脚本使用 TCP 连接与在主机上运行的程序进行交互,因此我为 Docker 容器设置了一个“主机”网络以允许这样做。 python 脚本当前正在与主机上的程序正常通信(TCP 通信符合预期)。 python 脚本还可以与在另一个容器中运行的 MySQL 数据库进行通信(pymysql 没有错误)。当我使用 Docker Desktop CLI 界面时,我可以看到数据库容器上 /var/lib/mysql/donuts/*.ibd 中文件的时间戳随着 python 代码将信息推送到表中而更新。

但是,我的问题是,当我使用 docker compose down 关闭两个容器,然后使用 docker compose up 再次打开它们时,数据库中的信息不会持久。实际上,如果我使用 CLI 使用 mysql -u donuts 进入数据库容器,然后在容器运行时尝试手动检查表,那么两个表都是完全空的。我一直在兜圈子,试图找出为什么我看不到表中的数据,即使我看到/var/lib/mysql/donuts/*.ibd 中的文件在 Python 容器插入行的同一实例中更新。当容器运行时,数据被存储在某个地方,至少是暂时的,因为 python 容器正在从其中一个表中读取并在容器处于活动状态时使用该信息。

下面是我的Dockerfiledocker-compose.yml 文件,整个项目可以在here 找到。与数据库交互的python代码是here,但我认为问题一定出在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 && \
    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

【问题讨论】:

    标签: python mysql docker docker-compose mysql-python


    【解决方案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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-08-13
      • 1970-01-01
      • 2017-01-03
      • 1970-01-01
      • 2020-04-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多