当我尝试使用命令测试任何应用程序时(当我尝试使用使用此命令的fabric部署myproject时我注意到了它):
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.
}
}
答案 0 :(得分:302)
当Django运行测试套件时,它会在您的案例test_finance
中创建一个新数据库。用户名为django
的postgres用户无权创建数据库,因此出现错误消息。
当您运行migrate
或syncdb
时,Django不会尝试创建finance
数据库,因此您不会收到任何错误。
您可以通过在postgres shell中以超级用户身份运行以下命令,将createdb权限添加到django用户(提示符为this stack overflow answer)。
=> ALTER USER django CREATEDB;
注意: ALTER USER <username> CREATEDB;
命令中使用的用户名需要与Django设置文件中的数据库用户匹配。在这种情况下,原始海报的用户为django
上述答案。
答案 1 :(得分:11)
我找到了解决问题的有趣方法。
事实上,对于MySQL,您可以为不存在的数据库授予权限
所以你可以添加名称&#39; test_finance&#39;对于您设置中的测试数据库:
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将毫无问题地开始测试。
答案 2 :(得分:3)
对于Postgres,用户必须具有createdb
权限。
ALTER ROLE miriam CREATEDB;
请参阅此文档:https://docs.djangoproject.com/en/2.0/topics/testing/overview/#the-test-database
答案 3 :(得分:2)
如果数据库是 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 workbench 键入以下命令,以便为 settings.py <中指定的用户提供所有权限/ p>
GRANT ALL PRIVILEGES ON myproject_test.* TO 'chandan'@'localhost';
现在您可以运行python manage.py test polls
。
答案 4 :(得分:1)
超级用户帐户是保证顺利测试的最简单方法。因此,使django
用户su更简单的方法是进行ALTER django WITH SUPERUSER
。
有关更多信息,https://www.postgresql.org/docs/current/sql-alteruser.html
答案 5 :(得分:0)
如果您使用的是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"
答案 6 :(得分: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:
答案 7 :(得分:0)
也许您将测试置于暂停模式或作为后台工作。尝试在bash shell中使用fg
命令。
答案 8 :(得分:0)
您也可以手动创建一个测试数据库,但将 TEST 键放在 settings.py 中
然后用值 'default' 填充传递 MIRROR 键,以便您可以测试默认数据库的精确副本,或您喜欢的任何数据库。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'finance',
'USER': 'django',
'TEST': {
'MIRROR': 'default',
},
'PASSWORD': 'mydb123',
'HOST': '127.0.0.1',
'PORT': '',
}
}
答案 9 :(得分:0)
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': ''
},
"TEST": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": os.path.join(BASE_DIR, "db.sqlite3"),
}}
else:
DATABASES = {
'default': {
"ENGINE": "django.db.backends.sqlite3",
"TEST": {
"NAME": os.path.join(BASE_DIR, "test_db.sqlite3"),
}
}}
答案 10 :(得分:-1)
就我而言,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'),
},
}
}
此后,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