创建测试数据库时出错 - django、docker、mysql

Posted

技术标签:

【中文标题】创建测试数据库时出错 - django、docker、mysql【英文标题】:Got an error creating the test database - django, docker, mysql 【发布时间】:2021-07-24 22:46:13 【问题描述】:

我在创建测试数据库时遇到问题。我将 mysql 用于 db 和 docker compose。

我用 docker-compose 运行 docker 容器没有问题,但是当我运行测试时它会吐出这个错误消息。

注意django服务名是web,mysql服务名是db。

$ docker-compose run --rm web sh -c "python manage.py test"
Creating sociallogin_web_run ... done
Creating test database for alias 'default'...
Got an error creating the test database: (1044, "Access denied for user 'myuser'@'%' to database 'test_mydb'")

我的docker-compose.yml: 版本:“3.9”

services:

  db:
    image: mysql:8
    env_file:
      - .env
    command: 
      - --default-authentication-plugin=mysql_native_password
    restart: always
    # ports:
    #   - "3306:3306"
    # volumes:
    #   - data:/var/lib/mysql

  web:
    build: .
    command: >
      sh -c "python manage.py wait_for_db &&
             python manage.py makemigrations && 
             python manage.py migrate && 
             python manage.py runserver 0.0.0.0:8000"
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on: 
      - db
    env_file:
      - .env

# volumes:
#   data:

我的.env 文件如下所示:

MYSQL_ROOT_PASSWORD=rootpass
MYSQL_USER=exampleuser
MYSQL_PASSWORD=examplepass
MYSQL_DATABASE=exampledb
MYSQL_PORT=3306
SECRET_KEY=exmaple_random_characters

settings.py 中的数据库

DATABASES = 
    'default': 
        'ENGINE': 'django.db.backends.mysql',
        'NAME': os.environ.get('MYSQL_DATABASE'),
        'USER': os.environ.get('MYSQL_USER'),
        'PASSWORD': os.environ.get('MYSQL_PASSWORD'),
        'PORT': os.environ.get('MYSQL_PORT'),
        'HOST': 'db',
        'TEST': 
            'NAME': 'test_mydb',
        
    

我查看了this,甚至尝试了this。这对我没有帮助。

有遇到类似问题的人吗?

提前谢谢大家。

【问题讨论】:

【参考方案1】:

正如K.D Singh所说,确实是mysql用户权限问题。

简而言之,初始化mysql容器时使用root用户。

不确定是什么让单独的用户无法进行测试。因为mysql docker hub 说

MYSQL_USER, MYSQL_PASSWORD 这些变量是可选的,用于创建新用户和设置该用户的密码。该用户将被授予对 MYSQL_DATABASE 变量指定的数据库的超级用户权限(见上文)。要创建用户,这两个变量都是必需的。

这是否意味着如果我创建用户和密码,那么它也具有创建数据库等超级用户权限?不知道为什么会出现权限问题。

不管怎样,下面是我改变的。

请注意,无需使用此机制来创建超级用户超级用户,默认情况下会使用 MYSQL_ROOT_PASSWORD 变量指定的密码创建该用户。

我将DATABASES 设置更改如下:

DATABASES = 
    'default': 
        'ENGINE': 'django.db.backends.mysql',
        'NAME': os.environ.get('MYSQL_DATABASE'),
        'PASSWORD': os.environ.get('MYSQL_ROOT_PASSWORD'),
        'PORT': os.environ.get('MYSQL_PORT'),
        'HOST': os.environ.get('MYSQL_HOST'),
    

所以基本上我删除了USER 密钥并用MYSQL_ROOT_PASSWORD 更新了PASSWORD,而不是绑定到MYSQL_USERMYSQL_PASSWORD,我启动了我的容器。

我的.env 文件有这样的变化:

MYSQL_ROOT_PASSWORD=myrootpassword
MYSQL_DATABASE=mydatabasename
MYSQL_PORT=3306
MYSQL_HOST=db
SECRET_KEY=random_secret_key_that_has_no_dollar_sign

我的docker-compose.yml:

version: "3.9"

services:

  db:
    image: mysql:8
    env_file:
      - .env
    command: 
      - --default-authentication-plugin=mysql_native_password
    restart: always
    ports:
      - "3308:3306"
    # volumes:
    #   - data:/var/lib/mysql

  web:
    build: .
    command: >
      sh -c "python manage.py wait_for_db &&
             python manage.py makemigrations && 
             python manage.py migrate && 
             python manage.py runserver 0.0.0.0:8000"
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on: 
      - db
    env_file:
      - .env

# volumes:
#   data:

有趣的是ports 部分,注意我设置了3308:3306。由于我已经有另一个使用默认端口3306 运行的mysql 容器,所以当我使用端口3306:3306 时,它不起作用。所以我只将外部端口更改为3308 和内部端口3306。由于 django 应用程序与内部端口通信,.env 文件的端口号保持为 3306。

【讨论】:

【参考方案2】:

我认为这是与 django 应用程序无关的问题,这看起来像基本的 mysql 错误,您尝试使用没有创建/管理数据库权限的用户创建/访问数据库,请通过 root 用户再次测试数据库。

您可以访问此网址ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'db' 获取。

【讨论】:

以上是关于创建测试数据库时出错 - django、docker、mysql的主要内容,如果未能解决你的问题,请参考以下文章

Django 测试:创建测试数据库时出错:数据库“database_name”已存在

加载夹具时 django unittest 出错

Django:为啥我在运行 LiveServerTestCase 测试时无法获得回溯(以防出错)?

Django:使用 from 创建对象时出错

Django 教程第 3 部分:创建视图和模板时出错

Django ORM - 检索数据时出错 -