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

后端 未结 9 930
甜味超标
甜味超标 2020-12-22 16:53

When I try to test any app with command (I noticed it when I tried to deploy myproject using fabric, which uses this command):

python manage.py test appname
         


        
相关标签:
9条回答
  • 2020-12-22 17:14

    Maybe you put your test in suspended mode or as a backgrounded job. Try with fg command in bash shell.

    0 讨论(0)
  • 2020-12-22 17:15

    When Django runs the test suite, it creates a new database, in your case test_finance. The postgres user with username django does not have permission to create a database, hence the error message.

    When you run migrate or syncdb, Django does not try to create the finance database, so you don't get any errors.

    You can add the createdb permission to the django user by running the following command in the postgres shell as a superuser (hat tip to this stack overflow answer).

    => ALTER USER django CREATEDB;
    

    Note: The username used in the ALTER USER <username> CREATEDB; command needs to match the database user in your Django settings files. In this case, the original poster, had the user as django the above answer.

    0 讨论(0)
  • 2020-12-22 17:21

    Wow so combining all of the answers here with a little tweaking finally got me to a working solution for docker-compose, django, and postgres...

    First the postgres command given by noufal valapra is not correct (or maybe just not current), it should be:

    ALTER USER docker WITH CREATEDB;
    

    In the case of a docker-compose setup, this will go in the init.sql file, this is what mine looks like:

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

    Then the Dockerfile for postgres looks like this:

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

    Then the Django settings.py has this entry:

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

    and the docker-compose looks like this:

    version: '3.6'

    services:

    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 讨论(0)
  • 2020-12-22 17:29

    I have found interesting solution to your problem.
    In fact for MySQL you can grant privileges for non-existing database.
    So you can add name 'test_finance' for your test database in your settings:

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

    start MySQL shell as the root user:

    mysql -u root -p
    

    and now grant all privileges to this non-existing database in MySQL:

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

    Now Django will start tests without any problems.

    0 讨论(0)
  • 2020-12-22 17:31

    A superuser account is the easiest way to guarantee smooth testing. so a simpler way of making the django user su is to do ALTER django WITH SUPERUSER .

    for more information https://www.postgresql.org/docs/current/sql-alteruser.html

    0 讨论(0)
  • 2020-12-22 17:32

    In the case of Postgres, the user must have createdb permission.

    ALTER ROLE miriam CREATEDB;
    

    See this documentation: https://docs.djangoproject.com/en/2.0/topics/testing/overview/#the-test-database

    0 讨论(0)
提交回复
热议问题