Ошибка приложения django test - получена ошибка при создании тестовой базы данных: разрешение отклонено для создания базы данных

Когда я пытаюсь протестировать любое приложение с помощью команды (я заметил это, когда попытался развернуть 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.
    }
}

Ответ 1

Когда Django запускает набор тестов, он создает новую базу данных, в вашем случае test_finance. Пользователь postgres с именем пользователя django не имеет разрешения на создание базы данных, поэтому появляется сообщение об ошибке.

Когда вы запускаете migrate или syncdb, Django не пытается создать finance базу данных, поэтому вы не получите никаких ошибок.

Вы можете добавить разрешение созданного пользователя django, выполнив следующую команду в оболочке postgres как суперпользователь (подсказка к этому ответу о переполнении стека).

=> ALTER USER django CREATEDB;

Примечание. Имя пользователя, используемое в ALTER USER <username> CREATEDB; Команда должна соответствовать пользователю базы данных в ваших файлах настроек Django. В этом случае, оригинальный постер, был пользователь как django выше ответ.

Ответ 2

Я нашел интересное решение вашей проблемы.
Фактически для 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',
        },
    }
}

запустите оболочку MySQL в качестве пользователя root:

mysql -u root -p

и теперь предоставить все привилегии этой несуществующей базе данных в MySQL:

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

Теперь Django начнет тесты без проблем.

Ответ 4

Если база данных 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 workbench, чтобы предоставить все привилегии пользователю, указанному в settings.py

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

Теперь вы можете запустить python manage.py test polls.

Ответ 5

Если вы используете 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"

Ответ 6

В моем случае решения GRANT PRIVILEGES не работали с Python 3.7.2, Django 2.1.7 и MySQL 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

Ответ 7

Ничего себе, объединяя все ответы здесь с небольшой настройкой, наконец, я получил рабочее решение для docker-compose, django и postgres...

Во-первых, команда postgres, данная noufal valapra, неверна (или, возможно, просто не актуальна), она должна быть:

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;

Тогда Dockerfile для postgres выглядит так:

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:

Ответ 8

Может быть, вы поставили свой тест в режиме приостановки или в качестве фоновой работы. Попробуйте с помощью команды fg в оболочке bash.