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

Когда я пытаюсь протестировать любое приложение с помощью команды (я заметил это, когда пытался развернуть свой проект с помощью ткани, которая использует эту команду):

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.
    }
}

person Andrius    schedule 06.01.2013    source источник


Ответы (11)


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

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

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

=> ALTER USER django CREATEDB;

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

person Alasdair    schedule 06.01.2013
comment
Хотя OP использовал postgresql, если вы используете mysql, у вас будет такая же ошибка. Вы можете исправить это для mysql с помощью: => GRANT ALL ON *.* TO django@localhost; Первоначально я пытался только GRANT CREATE... но потом не смог ВЫБРАТЬ или УДАЛИТЬ созданную базу данных. По сути, это делает вашего пользователя суперпользователем, так что будьте осторожны. - person mightypile; 31.12.2015
comment
Я немного поэкспериментировал и обнаружил, что минимальные глобальные привилегии: Данные: ВЫБРАТЬ, ВСТАВИТЬ, ОБНОВИТЬ, УДАЛИТЬ, Структура: СОЗДАТЬ, ИЗМЕНИТЬ, ИНДЕКС, УДАЛИТЬ, Админ: ССЫЛКИ. Не суперпользователь, но все же довольно мощный, так что будьте осторожны. - person Scott; 06.01.2016
comment
в моем случае я предоставляю все привилегии для тестовой базы данных, примерно так: GRANT ALL PRIVILEGES ON test_my_db.* TO 'my_user'@'localhost'; - person Yacine Rouizi; 11.04.2020

Я нашел интересное решение вашей проблемы.
На самом деле для 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 без проблем запустит тесты.

person Yurii Halapup    schedule 16.07.2017
comment
Я получаю ERROR 1410 (42000): You are not allowed to create a user with GRANT в оболочке mysql. Любая идея, пожалуйста? - person harryghgim; 01.05.2021
comment
Как видите, я запустил оболочку MySQL как пользователь root. - person Yurii Halapup; 21.05.2021

В случае Postgres пользователь должен иметь разрешение createdb.

ALTER ROLE miriam CREATEDB;

См. эту документацию: https://docs.djangoproject.com/en/2.0/topics/testing/overview/#the-test-database

person Noufal Valapra    schedule 05.03.2018

Если база данных 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.

person Chandan    schedule 30.07.2017
comment
Вопрос явно использует Postgres в качестве СУБД. К чему относится projectname_test? - person code-kobold; 30.07.2017
comment
@code-kobold 7, Да, но я вижу ту же ошибку и в mysql. Значение projectname_test относится к имени проекта, например, в моем ответе это мой проект. - person Chandan; 30.07.2017

В моем случае решения GRANT PRIVILEGES не работали с Python 3.7.2, Django 2.1.7 и MySQL 5.6.23... Я не знаю почему.

Поэтому я решил использовать SQLite в качестве тестовой базы данных...

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'),
        },
    }
}

После этого ТЕСТЫ машина работает без проблем:

$ 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
person JavierFuentes    schedule 10.03.2019
comment
Поначалу это казалось отличной идеей. Но я попробовал, и это, кажется, не работает. Теперь я вижу в документах, что указание ENGINE в TEST не вариант. Кроме того, я заметил, что вы закомментировали серверную часть MySQL и добавили коннектор. Что это? - person nicorellius; 20.10.2020

Если вы используете docker-compose, у меня сработало следующее:

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

or

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"
person lmiguelvargasf    schedule 28.09.2018

Вау, объединение всех ответов здесь с небольшой настройкой наконец-то привело меня к рабочему решению для 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:
person Paul Jacobs    schedule 01.05.2019

Учетная запись суперпользователя — это самый простой способ гарантировать гладкое тестирование. поэтому более простой способ сделать пользователя django su — это сделать ALTER django WITH SUPERUSER .

для получения дополнительной информации https://www.postgresql.org/docs/current/sql-alteruser.html

person スラッシュ    schedule 19.04.2020
comment
ALTER USER django WITH SUPERUSER, вы забыли ключевое слово USER. Я пытался отредактировать ваш пост, но очередь редактирования заполнена и не освобождается. - person run_the_race; 16.09.2020

Проверьте действия во время выполнения и переключите базу данных

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"),
        }
    }}
person 7guyo    schedule 05.03.2021

Возможно, вы поместили свой тест в приостановленный режим или в качестве фонового задания. Попробуйте использовать команду fg в оболочке bash.

person eEmanuel Oviedo    schedule 10.10.2019

Вы также можете просто создать тестовую базу данных вручную, но поместив ключ TEST в свой settings.py

Затем заполните ключ 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.

person Travis    schedule 14.01.2021