繁体   English   中英

django 测试应用程序错误 - 创建测试数据库时出错:创建数据库的权限被拒绝

[英]django test app error - Got an error creating the test database: permission denied to create database

当我尝试使用命令测试任何应用程序时(当我尝试使用使用此命令的 fabric 部署 myproject 时,我注意到了):

python manage.py test appname

我收到此错误:

Creating test database for alias 'default'...
Got an error creating the test database: permission denied to create database

Type 'yes' if you would like to try deleting the test database 'test_finance', or 'no' to cancel

syncdb命令似乎有效。 我在 settings.py 中的数据库设置:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'finance',                      # Or path to database file if using sqlite3.
        'USER': 'django',                      # Not used with sqlite3.
        'PASSWORD': 'mydb123',                  # Not used with sqlite3.
        'HOST': '127.0.0.1',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}

当 Django 运行测试套件时,它会创建一个新数据库,在您的情况下为test_finance 用户名为django的 postgres 用户没有创建数据库的权限,因此出现错误消息。

当您运行migratesyncdb ,Django 不会尝试创建finance数据库,因此您不会收到任何错误。

您可以通过在 postgres shell 中以超级用户身份运行以下命令来向 django 用户添加 createdb 权限( 此堆栈溢出答案的提示)。

=> ALTER USER django CREATEDB;

注意: ALTER USER <username> CREATEDB;使用的ALTER USER <username> CREATEDB; 命令需要匹配 Django 设置文件中的数据库用户。 在这种情况下,原始发布者将用户作为django了上述答案。

我为您的问题找到了有趣的解决方案。
事实上,对于 MySQL,您可以为不存在的数据库授予权限。
因此,您可以在设置中为测试数据库添加名称“test_finance”:

    DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'finance',                      # Or path to database file if using sqlite3.
        'USER': 'django',                      # Not used with sqlite3.
        'PASSWORD': 'mydb123',                  # Not used with sqlite3.
        'HOST': '127.0.0.1',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
        'TEST': {
            'NAME': 'test_finance',
        },
    }
}

以 root 用户身份启动 MySQL shell:

mysql -u root -p

现在将所有权限授予 MySQL 中这个不存在的数据库:

GRANT ALL PRIVILEGES ON test_finance.* TO 'django'@'localhost';

现在 Django 将开始测试,没有任何问题。

对于 Postgres,用户必须具有createdb权限。

ALTER ROLE miriam CREATEDB;

请参阅此文档: https : //docs.djangoproject.com/en/2.0/topics/testing/overview/#the-test-database

如果数据库是mysql,那么这两个更改将完成。

1.打开mysite/mysite/settings.py

您的数据库设置应该有一个额外的 TEST 块,如projectname_test所示。

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'myproject',
        'USER': 'chandan',
        'PASSWORD': 'root',
        'HOST': 'localhost',
        'PORT': '3306',
        'TEST': {
            'NAME': 'myproject_test',
        },
    }
}

2.使用mysql命令提示符mysql工作台键入以下命令,将所有权限授予settings.py中指定的用户

GRANT ALL PRIVILEGES ON myproject_test.* TO 'chandan'@'localhost';

现在您可以运行python manage.py test polls

就我而言, GRANT PRIVILEGES 解决方案不适用于Python 3.7.2Django 2.1.7MySQL 5.6.23 ......我不知道为什么。

所以我决定使用 SQLite 作为 TEST 数据库......

DATABASES = {
    'default': {
        'NAME': 'productiondb',
        'ENGINE': 'mysql.connector.django',   # 'django.db.backends.mysql'
        'USER': '<user>',
        'PASSWORD': '<pass>',
        'HOST': 'localhost',
        'PORT': 3306,
        'OPTIONS': {
            'autocommit': True,
        },
        'TEST': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        },
    }
}

之后,TESTS 车就顺利运行了:

$ python manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).

Destroying test database for alias 'default'...
----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK

Process finished with exit code 0

哇,所以结合这里的所有答案和一点点调整,终于让我找到了一个适用于 docker-compose、django 和 postgres 的工作解决方案......

首先 noufal valapra 给出的 postgres 命令不正确(或者可能不是最新的),它应该是:

ALTER USER docker WITH CREATEDB;

在 docker-compose 设置的情况下,这将进入 init.sql 文件,这是我的样子:

CREATE USER docker;
ALTER USER docker WITH CREATEDB;
CREATE DATABASE djangodb;
GRANT ALL PRIVILEGES ON DATABASE djangodb TO docker;

然后 postgres 的 Dockerfile 看起来像这样:

FROM postgres:10.1-alpine
COPY init.sql /docker-entrypoint-initdb.d/

然后 Django settings.py 有这个条目:

if 'RDS_DB_NAME' in os.environ:
    INTERNAL_DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': os.environ['RDS_DB_NAME'],
            'USER': os.environ['RDS_USERNAME'],
            'PASSWORD': os.environ['RDS_PASSWORD'],
            'HOST': os.environ['RDS_HOSTNAME'],
            'PORT': os.environ['RDS_PORT'],
        }
    }

docker-compose 看起来像这样:

版本:'3.6'

服务:

postgresdb:
  build:
    context: ./
    dockerfile: ./Dockerfile-postgresdb
  volumes:
    - postgresdata:/var/lib/postgresql/data/

django:
  build:
    context: ../
    dockerfile: ./docker/Dockerfile
  environment:
    - RDS_DB_NAME=djangodb
    - RDS_USERNAME=docker
    - RDS_PASSWORD=docker
    - RDS_HOSTNAME=postgresdb
    - RDS_PORT=5432

  stdin_open: true
  tty: true
  depends_on:
    - postgresdb

volumes:
    postgresdata:

如果您使用docker-compose对我docker-compose是以下内容:

ALTER ROLE username CREATEDB;
GRANT ALL PRIVILEGES ON test_database_name.* TO 'username';

要么

ALTER ROLE username CREATEDB;
GRANT ALL PRIVILEGES ON *.* TO 'username'@'%';

我的设置如下所示:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'database_name',
        'USER': 'username',
        'PASSWORD': 'password',
        'HOST': 'db',
        'PORT': '3306',
    }
}

docker-compose.yml如下所示:

version: '3'
services:
  web:
      build: .
      command: './wait_for_db_and_start_server.sh'
      env_file: env_web
      working_dir: /project_name
      links:
        - db
      volumes:
        - .:/volume_name
      ports:
        - "8000:8000"
      depends_on:
        - db
  db:
    image: mysql:5.7
    restart: always
    env_file: env_db
    working_dir: /db
    volumes:
      - ./Dump.sql:/db/Dump.sql
    ports:
      - "3306:3306"

超级用户帐户是保证顺利测试的最简单方法。 因此,使django用户 su 的更简单方法是ALTER django WITH SUPERUSER执行ALTER django WITH SUPERUSER

有关更多信息https://www.postgresql.org/docs/current/sql-alteruser.html

您也可以手动创建一个测试数据库,但将 TEST 键放在 settings.py 中

然后用值 'default' 填充传递 MIRROR 键,这样你就可以测试你的默认数据库的精确副本,或者你喜欢的任何数据库。

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'finance',
        'USER': 'django',
        'TEST': {
             'MIRROR': 'default',
        },
        'PASSWORD': 'mydb123',
        'HOST': '127.0.0.1',
        'PORT': '',
    }
}

您还可以查看 高级 django postgres 文档

检查运行时的操作并切换数据库

import sys
TESTING = sys.argv[1:2] == ['test']
if TESTING==False:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': config('DB_NAME'),
            'USER': config('DB_USER'),
            'PASSWORD': config('DB_PASSWORD'),
            'HOST': config('DB_HOST'),
            'PORT': ''
             }       
           }
else:
    DATABASES = {    
        'default': {
        "ENGINE": "django.db.backends.sqlite3",
        "TEST": {
            "NAME": os.path.join(BASE_DIR, "test_db.sqlite3"),
        }
    }}

我刚才遇到了同样的问题。 这就是我在 django 3.10.6 上解决问题的方法

首先使用此命令通过终端进入您的 dbshell

python3 manage.py dbshell

这将带你到你的项目数据库,即如果你已经创建了一个。 进入数据库的另一种方法是:

sudo su postgres

然后:

psql

这会将您带到默认数据库。 然后通过以下方式连接到您的项目数据库:

\c projectdb

此时使用此命令修复您的错误:

ALTER USER you CREATEDB;

用'\q'退出你的数据库; 使用'exit'退出postgres然后运行:

python3 manage.py test app

错误将被修复,您的测试将通过

Found 1 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.
----------------------------------------------------------------------
Ran 1 test in 0.003s

OK
Destroying test database for alias 'default'...

也许您将测试置于暂停模式或作为后台作业。 在 bash shell 中尝试使用fg命令。

通过键入以下内容切换到服务器上的 postgres 帐户:

sudo -i -u postgres

您现在可以通过键入以下内容立即访问 Postgres 提示:

psql

现在输入

ALTER USER username CREATEDB;

我面临同样的问题

pytest

我更改了 django 用户权限,以便它可以在运行 python 测试用例时创建测试数据库。

ALTER USER USERNAME CREATEDB;

由于错误表明用户没有足够的权限来创建数据库。 Django 在测试期间会创建一个单独的数据库,这样我们原来的开发数据库就不会受到影响。

我们可能需要通过 Postgres shell 授予权限。

DATABASES = {
'default': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': config('DB_NAME'),
    'USER': "myuser",
    'PASSWORD': config('DB_PASSWORD'),
    'HOST': config('DB_HOST'),
    'PORT': config('DB_PORT'),

    'TEST': {
        'NAME': 'test_nofoobar',
    },
}

}

正如设置所暗示的,在这种情况下,数据库用户的名称是myuser 因此,让我们启动 Postgres shell 并授予数据库创建权限。

sudo -u postgres psql


psql (14.5 (Ubuntu 14.5-1.pgdg22.04+1))

postgres=# ALTER ROLE myuser CREATEDB;
Output: ALTER ROLE

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM