Error de la aplicación de prueba Django: se produjo un error al crear la base de datos de prueba: permiso denegado para crear la base de datos

7 minutos de lectura

avatar de usuario
Andrio

Cuando trato de probar cualquier aplicación con el comando (lo noté cuando intenté implementar mi proyecto usando fabric, que usa este comando):

python manage.py test appname

me sale este error:

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 el comando parece funcionar. La configuración de mi base de datos en 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.
    }
}

avatar de usuario
Alasdair

Cuando Django ejecuta el conjunto de pruebas, crea una nueva base de datos, en su caso test_finance. El usuario de postgres con nombre de usuario django no tiene permiso para crear una base de datos, de ahí el mensaje de error.

cuando corres migrate o syncdbDjango no intenta crear el finance base de datos, para que no obtenga ningún error.

Puede agregar el permiso createdb al usuario django ejecutando el siguiente comando en el shell de postgres como superusuario (sugerencia para esta respuesta de desbordamiento de pila).

=> ALTER USER django CREATEDB;

Nota: El nombre de usuario utilizado en el ALTER USER <username> CREATEDB; El comando debe coincidir con el usuario de la base de datos en los archivos de configuración de Django. En este caso, el cartel original, tenía al usuario como django la respuesta anterior.

  • Aunque el OP usó postgresql, si está usando mysql tendrá el mismo error. Puede arreglarlo para mysql con: => GRANT ALL ON *.* TO [email protected]; Originalmente intenté solo CONCEDER CREAR… pero luego no pude SELECCIONAR o SOLTAR la base de datos creada. Básicamente, esto convierte a su usuario en un superusuario, así que tenga cuidado.

    – pila poderosa

    31 de diciembre de 2015 a las 16:28


  • Experimenté un poco y descubrí que los privilegios globales mínimos son – Datos: SELECCIONAR, INSERTAR, ACTUALIZAR, ELIMINAR, Estructura: CREAR, ALTERAR, INDIZAR, SOLTAR, Administrador: REFERENCIAS. No es un superusuario, pero sigue siendo bastante poderoso, así que tenga cuidado.

    – Scott

    06/01/2016 a las 17:52


  • para mi caso otorgo todos los privilegios a la base de datos de prueba, algo como esto: GRANT ALL PRIVILEGES ON test_my_db.* TO 'my_user'@'localhost';

    –Yacine Rouizi

    10 de abril de 2020 a las 22:08

avatar de usuario
yurii halapup

He encontrado una solución interesante a tu problema.
De hecho, para MySQL puede otorgar privilegios para una base de datos inexistente.
Entonces puede agregar el nombre ‘test_finance’ para su base de datos de prueba en su configuración:

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

inicie MySQL shell como usuario root:

mysql -u root -p

y ahora otorgue todos los privilegios a esta base de datos inexistente en MySQL:

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

Ahora Django comenzará las pruebas sin ningún problema.

  • yo obtengo ERROR 1410 (42000): You are not allowed to create a user with GRANT en shell mysql. ¿Alguna idea, por favor?

    – harryghgim

    1 de mayo de 2021 a las 6:44

  • Como puede ver, comencé MySQL Shell como usuario raíz.

    – Yuri Halapup

    21 de mayo de 2021 a las 7:37

  • me encanta esta respuesta esto no hace que el usuario del proyecto django se convierta en un superusuario de la base de datos

    – AcaNg

    2 de junio a las 5:49

avatar de usuario
Noufal Valapra

En el caso de Postgres, el usuario debe tener createdb permiso.

ALTER ROLE miriam CREATEDB;

Ver esta documentación: https://docs.djangoproject.com/en/2.0/topics/testing/overview/#the-test-database

Si la base de datos es mysql entonces estos dos cambios harán las cosas.

1.Abrir misitio/misitio/settings.py

La configuración de su base de datos debe tener un bloque de PRUEBA adicional como se muestra con nombre_proyecto_prueba.

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

2.Escriba el siguiente comando usando símbolo del sistema mysql o banco de trabajo mysql otorgar todos los privilegios al usuario especificado en configuración.py

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

Ahora puedes correr python manage.py test polls.

En mi caso, las soluciones GRANT PRIVILEGES no funcionaron con Pitón 3.7.2, Django 2.1.7 y MySQL 5.6.23… No sé por qué.

Así que decidí usar SQLite como base de datos de PRUEBA…

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

Después de eso, el coche TESTS funciona sin problemas:

$ 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

  • Al principio, esto parecía ser una gran idea. Pero lo probé y no parece funcionar. Ahora veo en los documentos que especificar ENGINE en TEST no es una opinión. Además, noté que comentaste el back-end de MySQL y agregaste el conector. ¿Que es eso?

    – nicorelio

    20 de octubre de 2020 a las 1:48

  • Parece que ha utilizado diferentes bases de datos para el entorno de producción y prueba. Puede que no sea una buena idea y puede causar errores específicos de la base de datos.

    – Joel G Mathew

    15 de diciembre de 2021 a las 6:01

avatar de usuario
pablo jacobs

Wow, la combinación de todas las respuestas aquí con un pequeño ajuste finalmente me llevó a una solución funcional para docker-compose, django y postgres…

Primero, el comando postgres dado por noufal valapra no es correcto (o tal vez simplemente no es actual), debería ser:

ALTER USER docker WITH CREATEDB;

En el caso de una configuración de docker-compose, esto irá en el archivo init.sql, así es como se ve el mío:

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

Luego, el Dockerfile para postgres se ve así:

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

Luego Django settings.py tiene esta entrada:

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

y el docker-compose se ve así:

versión: ‘3.6’

servicios:

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:

  • Al principio, esto parecía ser una gran idea. Pero lo probé y no parece funcionar. Ahora veo en los documentos que especificar ENGINE en TEST no es una opinión. Además, noté que comentaste el back-end de MySQL y agregaste el conector. ¿Que es eso?

    – nicorelio

    20 de octubre de 2020 a las 1:48

  • Parece que ha utilizado diferentes bases de datos para el entorno de producción y prueba. Puede que no sea una buena idea y puede causar errores específicos de la base de datos.

    – Joel G Mathew

    15 de diciembre de 2021 a las 6:01

Si estás usando docker-compose lo que funciono para mi fue lo siguiente:

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

o

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

Mi configuración se ve así:

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

y mi docker-compose.yml se ve de la siguiente manera:

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"

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad