django test app error -在创建测试数据库时出现错误:创建数据库的权限被拒绝

当我尝试用命令测试任何应用程序时(我注意到当我尝试使用fabric部署我的项目时,它使用了这个命令):

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.
}
}
107176 次浏览

当Django运行测试套件时,它会创建一个新的数据库,在你的例子中是test_finance。用户名为django的postgres用户没有创建数据库的权限,因此出现错误信息。

当你运行migratesyncdb时,Django不会尝试创建finance数据库,所以你不会得到任何错误。

你可以在postgres shell中以超级用户(这个堆栈溢出答案)的身份运行以下命令,为django用户添加createdb权限。

=> ALTER USER django CREATEDB;

注意: ALTER USER <username> CREATEDB;命令中使用的用户名需要与Django设置文件中的数据库用户相匹配。在这种情况下,最初的海报,有用户django上面的答案。

对于你的问题,我找到了一个有趣的解决办法。< br > 事实上,对于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',
},
}
}

以root用户启动MySQL shell:

mysql -u root -p

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

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

现在,Django将毫无问题地启动测试。

如果数据库是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工作台键入下面的命令,将所有特权赋予settings.py中指定的用户

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

现在你可以运行下面的命令:

python manage.py test polls

对于Postgres,用户必须具有createdb权限。

ALTER ROLE miriam CREATEDB;

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

如果你使用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"

在我的情况下,GRANT PRIVILEGES解决方案不能与Python 3.7.2章Django 2.1.7MySQL 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

哇,把这里所有的答案结合起来,稍加调整,终于让我得到了一个适用于docker-compose、django和postgres的解决方案……

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

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;

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

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:

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

超级用户帐户是保证测试顺利进行的最简单方法。因此,创建django用户su的更简单方法是执行ALTER django WITH SUPERUSER

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

您也可以手动创建一个测试数据库,但将test键放在settings.py中

然后用值'default'填充传递MIRROR键,这样你就可以测试默认db的精确副本,或者任何你喜欢的db。

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文档

检查运行时的操作并切换数据库

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

切换到postgres帐户在你的服务器输入:

sudo -i -u postgres

您现在可以通过输入以下命令立即访问Postgres提示:

psql

现在式

ALTER USER username CREATEDB;

我也面临着同样的问题

pytest

我修改了django的用户权限,这样它就可以在运行python测试用例时创建一个测试数据库。

ALTER USER USERNAME CREATEDB;

错误提示用户没有创建数据库的足够权限。Django会在测试期间创建一个单独的数据库,这样我们原来的开发数据库就不会受到影响。

我们可能需要通过Postgres shell给予权限。

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': config('DB_NAME'),
'USER': "myuser",
'PASSWORD': config('DB_PASSWORD'),
'HOST': config('DB_HOST'),
'PORT': config('DB_PORT'),


'TEST': {
'NAME': 'test_nofoobar',
},
}

正如设置所建议的,在本例中,数据库用户的名称是myuser。因此,让我们启动Postgres shell并授予数据库创建权限。

sudo -u postgres psql




psql (14.5 (Ubuntu 14.5-1.pgdg22.04+1))


postgres=# ALTER ROLE myuser CREATEDB;
Output: ALTER ROLE