Python django 测试应用程序错误 - 创建测试数据库时出错:创建数据库的权限被拒绝

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14186055/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 10:42:28  来源:igfitidea点击:

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

pythonsqldjangopostgresqldjango-testing

提问by Andrius

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

当我尝试使用命令测试任何应用程序时(当我尝试使用使用此命令的结构部署 myproject 时我注意到了这一点):

python manage.py test appname

I get this 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

syncdbcommand seems to work. My database settings in settings.py:

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

采纳答案by Alasdair

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

当 Django 运行测试套件时,它会创建一个新数据库,在您的情况下为test_finance. 具有用户名的 postgres 用户django无权创建数据库,因此出现错误消息。

When you run migrateor syncdb, Django does not try to create the financedatabase, so you don't get any errors.

当您运行migrate或 时syncdb,Django 不会尝试创建finance数据库,因此您不会收到任何错误。

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

您可以通过在 postgres shell 中以超级用户身份运行以下命令来向 django 用户添加 createdb 权限(此堆栈溢出答案的提示)。

=> 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 djangothe above answer.

注意:ALTER USER <username> CREATEDB;命令中使用的用户名需要与 Django 设置文件中的数据库用户匹配。在这种情况下,原始发布者的用户作为django上述答案。

回答by Yurii Halapup

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:

我为您的问题找到了有趣的解决方案。
事实上,对于 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',
        },
    }
}

start MySQL shell as the root user:

以 root 用户身份启动 MySQL shell:

mysql -u root -p

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

现在将所有权限授予 MySQL 中这个不存在的数据库:

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

Now Django will start tests without any problems.

现在 Django 将开始测试,没有任何问题。

回答by Chandan

If database is mysqlthen these two changes will get the things done.

如果数据库是mysql,那么这两个更改将完成。

1.Open mysite/mysite/settings.py

1.打开mysite/mysite/settings.py

Your database settings should have an additional TEST block as shown with projectname_test.

您的数据库设置应该有一个额外的 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.Type the below command using mysql command promptor mysql workbenchto give all privilages to the user specified in settings.py

2.使用mysql命令提示符mysql工作台键入以下命令,将所有权限授予settings.py中指定的用户

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

Now you can run python manage.py test polls.

现在您可以运行 python manage.py test polls.

回答by Noufal Valapra

In the case of Postgres, the user must have createdbpermission.

在 Postgres 的情况下,用户必须有createdb权限。

ALTER ROLE miriam CREATEDB;

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

请参阅此文档:https: //docs.djangoproject.com/en/2.0/topics/testing/overview/#the-test-database

回答by lmiguelvargasf

If you are using docker-composewhat worked for me was the following:

如果您正在使用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'@'%';

My settings looks like this:

我的设置如下所示:

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

and my docker-compose.ymllooks as follows:

我的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"

回答by JavierFuentes

In my case, GRANT PRIVILEGES solutions didn't work with Python 3.7.2, Django 2.1.7and MySQL 5.6.23... I don't know why.

就我而言, GRANT PRIVILEGES 解决方案不适用于Python 3.7.2Django 2.1.7MySQL 5.6.23......我不知道为什么。

So I decided to use SQLite as a TEST database...

所以我决定使用 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'),
        },
    }
}

After that, TESTS car run without troubles:

之后,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

回答by Paul Jacobs

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

哇,所以结合这里的所有答案和一点点调整,终于让我找到了一个适用于 docker-compose、django 和 postgres 的工作解决方案......

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

首先 noufal valapra 给出的 postgres 命令不正确(或者可能不是最新的),它应该是:

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:

在 docker-compose 设置的情况下,这将进入 init.sql 文件,这是我的样子:

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:

然后 postgres 的 Dockerfile 看起来像这样:

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

Then the Django settings.py has this entry:

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

and the docker-compose looks like this:

docker-compose 看起来像这样:

version: '3.6'

版本:'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:

回答by eEmanuel Oviedo

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

也许您将测试置于暂停模式或作为后台作业。fg在 bash shell 中尝试使用命令。

回答by スラッシュ

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

超级用户帐户是保证顺利测试的最简单方法。所以让django用户 su 的一种更简单的方法是做ALTER django WITH SUPERUSER.

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

有关更多信息https://www.postgresql.org/docs/current/sql-alteruser.html