django test app error - Mendapat kesalahan membuat database pengujian: izin ditolak untuk membuat database

181

Ketika saya mencoba menguji aplikasi apa pun dengan perintah (saya perhatikan ketika saya mencoba menggunakan myproject menggunakan fabric, yang menggunakan perintah ini):

python manage.py test appname

Saya mendapatkan kesalahan ini:

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

syncdbPerintah tampaknya berhasil. Pengaturan basis data saya di 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.
    }
}
Andrius
sumber

Jawaban:

373

Ketika Django menjalankan test suite, itu membuat database baru, dalam kasus Anda test_finance. Pengguna postgres dengan nama pengguna djangotidak memiliki izin untuk membuat database, karenanya pesan kesalahan.

Saat Anda menjalankan migrateatau syncdb, Django tidak mencoba membuat financedatabase, jadi Anda tidak mendapatkan kesalahan.

Anda dapat menambahkan izin yang dibuat ke pengguna django dengan menjalankan perintah berikut di postgres shell sebagai superuser (tip topi untuk jawaban stack overflow ini ).

=> ALTER USER django CREATEDB;

Catatan: Nama pengguna yang digunakan dalam ALTER USER <username> CREATEDB;perintah harus sesuai dengan pengguna basis data dalam file pengaturan Django Anda. Dalam hal ini, poster asli, memiliki pengguna sebagai djangojawaban di atas.

Alasdair
sumber
2
Meskipun OP menggunakan postgresql, jika Anda menggunakan mysql Anda akan memiliki kesalahan yang sama. Anda dapat memperbaikinya untuk mysql dengan: => GRANT ALL ON *. * TO django @ localhost; Saya awalnya mencoba hanya MENCIPTAKAN GRANT ... tetapi kemudian tidak dapat MEMILIH atau MENGURANGI database yang dibuat. Ini pada dasarnya membuat pengguna Anda pengguna super, jadi berhati-hatilah.
mayypile
1
Saya bereksperimen sedikit dan menemukan priviledges global minimum adalah - Data: SELECT, INSERT, UPDATE, DELETE, Struktur: CREATE, ALTER, INDEX, DROP, Admin: REFERENSI. Bukan pengguna super, tapi masih cukup kuat, jadi berhati-hatilah.
Scott
untuk kasus saya, saya memberikan semua hak istimewa ke database tes te, sesuatu seperti ini:GRANT ALL PRIVILEGES ON test_my_db.* TO 'my_user'@'localhost';
Yacine Rouizi
17

Saya telah menemukan solusi menarik untuk masalah Anda.
Bahkan untuk MySQL Anda dapat memberikan hak istimewa untuk database yang tidak ada.
Jadi, Anda dapat menambahkan nama 'test_finance' untuk database pengujian di pengaturan Anda:

    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',
        },
    }
}

mulai shell MySQL sebagai pengguna root:

mysql -u root -p

dan sekarang berikan semua hak istimewa ke basis data yang tidak ada ini di MySQL:

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

Sekarang Django akan memulai tes tanpa masalah.

Yurii Halapup
sumber
4

Jika database adalah mysql maka kedua perubahan ini akan menyelesaikan semuanya.

1.Buka mysite / mysite / settings.py

Pengaturan database Anda harus memiliki blok TEST tambahan seperti yang ditunjukkan dengan projectname_test .

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'myproject',
        'USER': 'chandan',
        'PASSWORD': 'root',
        'HOST': 'localhost',
        'PORT': '3306',
        'TEST': {
            'NAME': 'myproject_test',
        },
    }
}

2. Ketik perintah di bawah ini menggunakan mysql command prompt atau mysql workbench untuk memberikan semua hak istimewa kepada pengguna yang ditentukan dalam settings.py

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

Sekarang kamu bisa lari python manage.py test polls.

Chandan
sumber
Pertanyaannya jelas menggunakan Postgres sebagai DBMS. Apa yang akan terkait dengan projectname_test ?
kode-kobold
@ code-kobold 7, Ya, tetapi saya dapat melihat kesalahan yang sama di mysql juga. Nilai projectname_test merujuk pada nama proyek ex.in jawaban saya itu adalah myproject.
Chandan
1

Jika Anda menggunakan docker-composeapa yang berfungsi untuk saya adalah sebagai berikut:

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

atau

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

Pengaturan saya terlihat seperti ini:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'database_name',
        'USER': 'username',
        'PASSWORD': 'password',
        'HOST': 'db',
        'PORT': '3306',
    }
}

dan docker-compose.ymlpenampilan saya sebagai berikut:

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"
lmiguelvargasf
sumber
1

Dalam kasus saya, solusi GRANT PRIVILEGES tidak bekerja dengan Python 3.7.2 , Django 2.1.7 dan MySQL 5.6.23 ... Saya tidak tahu mengapa.

Jadi saya memutuskan untuk menggunakan SQLite sebagai database 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'),
        },
    }
}

Setelah itu, TESTS mobil berjalan tanpa masalah:

$ 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
JavierFuentes
sumber
0

Wow jadi menggabungkan semua jawaban di sini dengan sedikit penyesuaian akhirnya membuat saya menjadi solusi yang berfungsi untuk menyusun-buruh pelabuhan, Django, dan postgres ...

Pertama perintah postgres yang diberikan oleh noufal valapra tidak benar (atau mungkin tidak saat ini), seharusnya:

ALTER USER docker WITH CREATEDB;

Dalam hal pengaturan susunan buruh pelabuhan, ini akan masuk dalam file init.sql, seperti inilah milik saya:

CREATE USER docker;
ALTER USER docker WITH CREATEDB;
CREATE DATABASE djangodb;
GRANT ALL PRIVILEGES ON DATABASE djangodb TO docker;

Maka Dockerfile untuk postgres terlihat seperti ini:

FROM postgres:10.1-alpine
COPY init.sql /docker-entrypoint-initdb.d/

Kemudian Django settings.py memiliki entri ini:

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'],
        }
    }

dan susunan buruh pelabuhan terlihat seperti ini:

versi: '3.6'

jasa:

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:
Paul Jacobs
sumber
0

Mungkin Anda meletakkan tes dalam mode ditangguhkan atau sebagai pekerjaan latar belakang. Coba dengan fgperintah dalam bash shell.

eEmanuel Oviedo
sumber