djangoテストアプリエラー-テストデータベースの作成中にエラーが発生しました:データベースを作成する権限が拒否されました


181

コマンドを使用してアプリをテストしようとしたとき(このコマンドを使用するファブリックを使用して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.
    }
}

回答:


373

Djangoがテストスイートを実行すると、新しいデータベースが作成されますtest_finance。ユーザー名を持つpostgresユーザーにはdjango、データベースを作成する権限がないため、エラーメッセージが表示されます。

migrateまたはを実行するとsyncdb、Djangoはfinanceデータベースを作成しようとしないため、エラーは発生しません。

createbパーミッションをdjangoユーザーに追加するには、postgresシェルでスーパーユーザーとしてこのコマンドを実行します(このスタックオーバーフローの回答のヒント)。

=> ALTER USER django CREATEDB;

注:ALTER USER <username> CREATEDB;コマンドで使用するユーザー名は、Django設定ファイルのデータベースユーザーと一致する必要があります。この場合、元の投稿者はdjango、上記の答えとしてユーザーを持っています。


2
OPはpostgresqlを使用しましたが、mysqlを使用している場合も同じエラーが発生します。あなたはそれをmysqlのために修正することができます:=> GRANT ALL ON *。* TO django @ localhost; 最初はGRANT CREATEのみを試みましたが、作成したデータベースをSELECTまたはDROPできませんでした。これは基本的にユーザーをスーパーユーザーにするので注意してください。
mightypile 2015

1
私は少し実験して、最小のグローバル権限が-データ:SELECT、INSERT、UPDATE、DELETE、構造:CREATE、ALTER、INDEX、DROP、Admin:REFERENCESであることを発見しました。スーパーユーザーではありませんが、それでもかなり強力なので、注意してください。
スコット

私の場合のために、私はこのように、TEテストデータベースに何かをすべてpriviligesを付与しますGRANT ALL PRIVILEGES ON test_my_db.* TO 'my_user'@'localhost';
Yacine Rouizi

17

あなたの問題に対する興味深い解決策を見つけました。
実際、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',
        },
    }
}

MySQLシェルをrootユーザーとして起動します。

mysql -u root -p

そして、MySQLのこの存在しないデータベースにすべての特権を付与します。

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

Djangoは問題なくテストを開始します。



4

データベースが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コマンドプロンプトまたはmysqlワークベンチを使用して以下のコマンドを入力し、settings.pyで指定されたユーザーにすべての権限を付与します。

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

これで実行できます python manage.py test polls


質問は明らかにDBMSとしてPostgresを使用しています。projectname_testは何に関係しますか?
code-kobold 2017

@ code-kobold 7、はい、しかし、mysqlでも同じエラーが表示されます。値projectname_testは、プロジェクトの名前を参照しています。私の答えでは、myprojectです。
Chandan 2017

1

あなたが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"

1

私の場合、GRANT PRIVILEGESソリューションは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'),
        },
    }
}

その後、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

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:

0

テストを一時停止モードにするか、バックグラウンドジョブとして実行します。fgbashシェルのコマンドで試してください。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.