django test app error - Помилка створення тестової бази даних: дозвіл відмовлено у створенні бази даних


181

Коли я намагаюся протестувати будь-яку програму з командою (я помітив це, коли я намагався розгорнути свій проект за допомогою тканини, яка використовує цю команду):

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

Відповіді:


373

Коли Django запускає тестовий набір, він створює нову базу даних у вашому випадку test_finance. Користувач postgres з ім'ям користувача djangoне має дозволу на створення бази даних, отже, повідомлення про помилку.

Під час запуску migrateабо syncdbDjango не намагається створити financeбазу даних, тому ви не отримуєте жодних помилок.

Ви можете додати створений дозвіл користувачеві django, виконавши наступну команду в оболонці postgres як суперпользователь (підказка шапки до цієї відповіді на переповнення стека ).

=> ALTER USER django CREATEDB;

Примітка: ім'я користувача, яке використовується в ALTER USER <username> CREATEDB;команді, має відповідати користувачеві бази даних у файлах налаштувань Django. У цьому випадку оригінальний плакат мав користувача як djangoвідповідь вище.


2
Хоча в ОП використовується postgresql, якщо ви використовуєте mysql, у вас буде така ж помилка. Ви можете виправити це для mysql за допомогою: => ВІДКЛЮЧИТИ ВСІ НА *. * ДО django @ localhost; Спочатку я намагався створити лише ГРАНТ СТВОРИТИ ..., але потім не зміг ВИБІРИТИ або Зняти створену базу даних. Це по суті робить вашого користувача супер-користувачем, тому будьте обережні.
могучий

1
Я трохи експериментував і виявив, що мінімальні глобальні привілеї - Дані: SELECT, INSERT, UPDATE, DELETE, Структура: CREATE, ALTER, INDEX, DROP, Admin: REFERENCES. Не суперкористувач, але все ще досить потужний, тому будьте обережні.
Скотт

для мого випадку я надаю всі права доступу до тестової бази даних, приблизно так:GRANT ALL PRIVILEGES ON test_my_db.* TO 'my_user'@'localhost';
Yacine Rouizi

17

Я знайшов цікаве рішення вашої проблеми.
Насправді для 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';

Тепер Джанго почне тести без проблем.



4

Якщо база даних mysql, то ці дві зміни допоможуть зробити це.

1.Закрийте mysite / mysite / settings.py

У налаштуваннях вашої бази даних повинен бути додатковий блок 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.


Очевидно, що питання використовує Postgres як СУБД. Що стосується projektname_test ?
code-kobold

@ code-kobold 7, Так, але я можу бачити ту ж помилку і в mysql. Значення projectname_test посилається на ім'я проекту ex.in моя відповідь - це мій проект.
Чандан

2

У моєму випадку рішення 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'),
        },
    }
}

Після цього автомобіль ТЕСТИ працює без проблем:

$ 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

1

Якщо ви використовуєте 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"

0

Отож, поєднання всіх відповідей тут з невеликим налаштуванням нарешті привело мене до робочого рішення для докер-композиту, джанго та постгресу ...

По-перше, команда postgres, задана noufal valapra, не є правильною (а може просто не є актуальною), вона повинна бути:

ALTER USER docker WITH CREATEDB;

У випадку встановлення докер-композиції це відбудеться у файлі init.sql, так виглядає моя:

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

Тоді 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'],
        }
    }

і докер-композиція виглядає так:

версія: '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:

0

Можливо, ви поставили тест у призупиненому режимі або як фонове завдання. Спробуйте з fgкомандою в bash shell.


0

Обліковий запис суперпользователя - це найпростіший спосіб гарантувати плавне тестування. тому простіший спосіб зробити djangoкористувачеві су - це зробити ALTER django WITH SUPERUSER.

для отримання додаткової інформації https://www.postgresql.org/docs/current/sql-alteruser.html

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.