ข้อผิดพลาดของแอปทดสอบ 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หรือsyncdbDjango ไม่พยายามสร้างfinanceฐานข้อมูลดังนั้นคุณจะไม่ได้รับข้อผิดพลาดใด ๆ

คุณสามารถเพิ่มได้รับอนุญาต createdb ให้กับผู้ใช้ Django โดยการเรียกใช้คำสั่งต่อไปนี้ใน postgres เชลล์เป็น (ปลายหมวกเพื่อ superuser นี้คำตอบที่แตกล้น )

=> ALTER USER django CREATEDB;

หมายเหตุ:ชื่อผู้ใช้ที่ใช้ในALTER USER <username> CREATEDB;คำสั่งนั้นจะต้องตรงกับผู้ใช้ฐานข้อมูลในไฟล์การตั้งค่า Django ของคุณ ในกรณีนี้โปสเตอร์ดั้งเดิมมีผู้ใช้เป็นdjangoคำตอบข้างต้น


2
แม้ว่า OP ใช้ postgresql แต่ถ้าคุณใช้ mysql คุณจะมีข้อผิดพลาดเหมือนกัน คุณสามารถแก้ไขสำหรับ mysql ด้วย: => GRANT ALL ON *. * TO django @ localhost; ฉันพยายามสร้าง GRANT CREATE เท่านั้น แต่ไม่สามารถเลือกหรือวางฐานข้อมูลที่สร้างขึ้นได้ สิ่งนี้จะทำให้ผู้ใช้ของคุณเป็น superuser ดังนั้นโปรดระมัดระวัง
อันยิ่งใหญ่

1
ฉันทำการทดลองเล็กน้อยและพบว่าสิทธิ์ขั้นต่ำทั่วโลกคือ - ข้อมูล: SELECT, INSERT, UPDATE, DELETE, โครงสร้าง: CREATE, ALTER, INDEX, DROP, Admin: ข้อมูลอ้างอิง ไม่ใช่ผู้ใช้ระดับสูง แต่ยังทรงพลังมากดังนั้นโปรดใช้ความระมัดระวัง
สกอตต์

สำหรับกรณีของฉันฉันให้สิทธิ์ทั้งหมดเพื่อทดสอบฐานข้อมูลบางอย่างเช่นนี้: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 shell ในฐานะผู้ใช้รูท:

mysql -u root -p

และตอนนี้ให้สิทธิ์ทั้งหมดกับฐานข้อมูลที่ไม่มีอยู่ใน MySQL:

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

ตอนนี้ Django จะเริ่มการทดสอบโดยไม่มีปัญหาใด ๆ



4

หากฐานข้อมูลเป็นmysqlการเปลี่ยนแปลงสองอย่างนี้จะทำให้เสร็จ

1. เปิดmysite / mysite / settings.py

การตั้งค่าฐานข้อมูลของคุณควรจะมีบล็อกทดสอบเพิ่มเติมตามที่แสดงด้วย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

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

python manage.py test pollsตอนนี้คุณสามารถเรียกใช้


คำถามนี้เห็นได้ชัดว่าใช้ Postgres เป็น DBMS สิ่งที่จะprojectname_testเกี่ยวข้องกับ?
code-kobold

@ code-kobold 7 ใช่ แต่ฉันสามารถเห็นข้อผิดพลาดเดียวกันใน mysql เช่นกันค่า projectname_test หมายถึงชื่อของโครงการ ex.in คำตอบของฉันคือ myproject
Chandan

2

ในกรณีของฉันโซลูชันของ GRANT PRIVILEGES ไม่ทำงานกับPython 3.7.2 , Django 2.1.7และMySQL 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

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"

0

ว้าวดังนั้นการรวมคำตอบทั้งหมดที่นี่เข้ากับการปรับแต่งเล็กน้อยในที่สุดก็พาฉันไปหาวิธีการทำงานสำหรับนักแต่งเพลงนักแต่งเพลง django และ postgres ...

ก่อนอื่นคำสั่ง postgres ที่กำหนดโดย noufal valapra นั้นไม่ถูกต้อง (หรืออาจจะไม่ใช่ในปัจจุบัน) ก็ควรจะ:

ALTER USER docker WITH CREATEDB;

ในกรณีที่มีการตั้งค่านักเทียบท่าสิ่งนี้จะอยู่ในไฟล์ init.sql นี่คือลักษณะของฉัน:

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

จากนั้น Dockerfile สำหรับ postgres จะมีลักษณะดังนี้:

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

และนักเทียบท่าแต่งทำนองนี้:

รุ่น: '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

บางทีคุณอาจทำให้การทดสอบของคุณอยู่ในโหมดระงับหรือเป็นงานที่มีพื้นหลัง ลองด้วยfgคำสั่งใน bash shell


0

บัญชี superuser เป็นวิธีที่ง่ายที่สุดในการรับประกันการทดสอบที่ราบรื่น ดังนั้นวิธีที่ง่ายในการทำdjangoผู้ใช้ su ALTER django WITH SUPERUSERคือการทำ

สำหรับข้อมูลเพิ่มเติมhttps://www.postgresql.org/docs/current/sql-alteruser.html

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.