You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Docker Client无法正确执行MySQL命令,求助排查解决

Troubleshooting MySQL Initialization Script Execution via Docker Python Client

Let's break down why your initialization script isn't running and fix it step by step:

1. Shell Redirection Isn't Being Processed (The Most Likely Culprit)

When you use exec_run() without specifying shell=True, Docker executes the command directly without passing it through a shell. That means the < redirection symbol isn't interpreted—it's just treated as a regular argument to the mysql command, which is why your script isn't being loaded.

Fixes:

Option 1: Enable shell execution to let the shell handle the redirection:

er = container.exec_run(
    'mysql -h localhost < /data/init.sql',
    shell=True  # This is the key addition
)

Option 2: Avoid shell redirection entirely by using MySQL's built-in source command:

er = container.exec_run(
    ['mysql', '-h', 'localhost', '-e', 'source /data/init.sql']
)

2. MySQL Might Not Be Ready When You Run the Script

Docker containers start quickly, but MySQL needs a few seconds to initialize its data directory and start accepting connections. If you run exec_run() immediately after starting the container, the database might not be up yet.

Fix: Add a wait loop to check if MySQL is ready

import time

def wait_for_mysql(container):
    while True:
        # Use mysqladmin to check if the server is responsive
        result = container.exec_run('mysqladmin ping -h localhost --silent')
        if result.exit_code == 0:
            print("MySQL is ready!")
            break
        print("Waiting for MySQL to start...")
        time.sleep(1)

# Wait for MySQL to be ready before running the script
wait_for_mysql(container)
er = container.exec_run('mysql -h localhost < /data/init.sql', shell=True)

3. Better Alternative: Use MySQL Docker Image's Built-in Initialization

The official MySQL Docker image has a built-in feature that automatically runs scripts placed in /docker-entrypoint-initdb.d/ when the container starts for the first time. This is more reliable because the image handles waiting for MySQL to be ready before executing the scripts.

How to implement this:

Modify your volumes configuration to mount your init.sql directly into this directory:

volumes={
    f"{path_to_current_dir}/init.sql": {
        'bind': '/docker-entrypoint-initdb.d/init.sql',
        'mode': 'ro'
    },
}

With this setup, you can remove the exec_run() call entirely—MySQL will run your script automatically during initialization.


内容的提问来源于stack exchange,提问作者Most Wanted

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:28:10