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

Python django测试应用程序错误-创建测试数据库时出错:创建数据库的权限被拒绝,python,sql,django,postgresql,django-testing,Python,Sql,Django,Postgresql,Django Testing,当我尝试使用命令测试任何应用程序时(我在尝试使用fabric部署myproject时注意到了这一点,fabric使用此命令): 我得到这个错误: 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 tes

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

我得到这个错误:

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

当Django运行测试套件时,它会创建一个新的数据库,在您的例子中是
test\u finance
。用户名为django的postgres用户没有创建数据库的权限,因此会显示错误消息

运行
migrate
syncdb
时,Django不会尝试创建
finance
数据库,因此不会出现任何错误

您可以通过在postgres shell中以超级用户身份运行以下命令(hat-tip-to)向django用户添加createdb权限


注意:ALTER USER CREATEDB中使用的用户名命令需要匹配Django设置文件中的数据库用户。在本例中,原始海报让用户作为
django
给出了上述答案。

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

GRANT ALL PRIVILEGES ON myproject_test.* TO 'chandan'@'localhost';
您的数据库设置应该有一个额外的测试块,如projectname\u 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;

请参阅此文档:

如果您使用的是
docker compose
对我有效的方法如下:

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

我的设置如下所示:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'database_name',
        'USER': 'username',
        'PASSWORD': 'password',
        'HOST': 'db',
        'PORT': '3306',
    }
}
FROM postgres:10.1-alpine
COPY init.sql /docker-entrypoint-initdb.d/
我的
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"

在我的例子中,授予特权解决方案不适用于Python 3.7.2Django 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'),
        },
    }
}

哇,把这里所有的答案结合起来,再稍加调整,我终于找到了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如下所示:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'database_name',
        'USER': 'username',
        'PASSWORD': 'password',
        'HOST': 'db',
        'PORT': '3306',
    }
}
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如下所示:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'database_name',
        'USER': 'username',
        'PASSWORD': 'password',
        'HOST': 'db',
        'PORT': '3306',
    }
}
FROM postgres:10.1-alpine
COPY init.sql /docker-entrypoint-initdb.d/
版本:“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:

也许你把你的测试放在暂停模式或作为一个背景工作。在bashshell中尝试使用
fg
命令。

超级用户帐户是保证顺利测试的最简单方法。因此,使
django
用户su更简单的方法是使用超级用户
改变django


有关详细信息

您也可以手动创建测试数据库,但将测试密钥放入您的设置中。py

然后用值'default'填充并传递镜像键,这样您就可以测试默认数据库的精确副本,或者您喜欢的任何数据库

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'finance',
        'USER': 'django',
        'TEST': {
             'MIRROR': 'default',
        },
        'PASSWORD': 'mydb123',
        'HOST': '127.0.0.1',
        'PORT': '',
    }
}
您还可以检查

在运行时检查操作并切换数据库
虽然OP使用了postgresql,但是如果您使用的是mysql,那么您也会遇到同样的错误。您可以通过:=>GRANT ALL ON**来修复mysqldjango@localhost; 我最初试图只授权创建。。。但随后无法选择或删除创建的数据库。这本质上会让你的用户成为超级用户,所以要小心。我做了一些实验,发现最小的全局权限是-数据:选择、插入、更新、删除、结构:创建、更改、索引、删除、管理员:引用。不是超级用户,但仍然非常强大,所以请小心。在我的情况下,我将所有权限授予te测试数据库,类似这样:
grant all PRIVILEGES ON test_my_db.*授予'my_user'@'localhost'用SUPERUSER
更改用户django,您忘记了
用户
关键字。我试着编辑你的文章,但是编辑已经满了,无法释放。起初,这似乎是个好主意。但我试过了,似乎不起作用。我现在在文档中看到,在
TEST
中指定
ENGINE
。另外,我注意到您注释掉了MySQL后端并添加了连接器。那是什么?我得到
错误1410(42000):不允许您在mysql shell中创建具有GRANT
的用户。你知道吗?正如你所看到的,我已经以root用户的身份启动了MySQL shell。