コマンドでアプリをテストしようとすると(このコマンドを使用するファブリックを使用して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.
}
}
Djangoがテストスイートを実行すると、新しいデータベース、場合によってはtest_finance
が作成されます。ユーザー名がDjango
のpostgresユーザーには、データベースを作成する権限がないため、エラーメッセージが表示されます。
migrate
またはsyncdb
を実行すると、Djangoはfinance
データベースを作成しようとしないため、エラーは発生しません。
スーパーユーザーとしてpostgresシェルで次のコマンドを実行することにより、createdb権限をDjangoユーザーに追加できます( this stack overflow answer のヒント)。
=> ALTER USER Django CREATEDB;
注:ALTER USER <username> 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が問題なくテストを開始します。
Postgresの場合、ユーザーにはcreatedb
権限が必要です。
ALTER ROLE miriam CREATEDB;
このドキュメントを参照してください: https://docs.djangoproject.com/en/2.0/topics/testing/overview/#the-test-database
データベースがmysqlの場合、これらの2つの変更により処理が完了します。
1.開くmysite/mysite/settings.py
projectname_testで示されているように、データベース設定に追加のTESTブロックが必要です。
DATABASES = {
'default': {
'ENGINE': 'Django.db.backends.mysql',
'NAME': 'myproject',
'USER': 'chandan',
'PASSWORD': 'root',
'Host': 'localhost',
'PORT': '3306',
'TEST': {
'NAME': 'myproject_test',
},
}
}
2. mysql command Promptまたはmysql workbenchを使用して以下のコマンドを入力し、settings.pyで指定されたユーザーにすべての特権を付与します
GRANT ALL PRIVILEGES ON myproject_test.* TO 'chandan'@'localhost';
これで、python manage.py test polls
を実行できます。
私の場合、GRANT PRIVILEGESソリューションはPython 3.7.2、Django 2.1.7およびMySQL 5.6.2 ...では機能しませんでした理由はわかりません。
そこで、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
ここですべての答えを少し調整して組み合わせることで、ついに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:
あなたが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"