lỗi ứng dụng kiểm tra django - Có lỗi khi tạo cơ sở dữ liệu kiểm tra: quyền bị từ chối để tạo cơ sở dữ liệu


181

Khi tôi thử kiểm tra bất kỳ ứng dụng nào bằng lệnh (tôi nhận thấy nó khi tôi cố gắng triển khai myproject bằng vải, sử dụng lệnh này):

python manage.py test appname

Tôi nhận được lỗi này:

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

syncdblệnh dường như làm việc. Cài đặt cơ sở dữ liệu của tôi trong 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.
    }
}

Câu trả lời:


372

Khi Django chạy bộ thử nghiệm, nó sẽ tạo ra một cơ sở dữ liệu mới, trong trường hợp của bạn test_finance. Người dùng postgres với tên người dùng djangokhông có quyền tạo cơ sở dữ liệu, do đó thông báo lỗi.

Khi bạn chạy migratehoặc syncdb, Django không cố gắng tạo financecơ sở dữ liệu, do đó bạn không gặp phải bất kỳ lỗi nào.

Bạn có thể thêm quyền được tạo cho người dùng django bằng cách chạy lệnh sau trong shell postgres dưới dạng siêu người dùng (mẹo mũ cho câu trả lời tràn ngăn xếp này ).

=> ALTER USER django CREATEDB;

Lưu ý: Tên người dùng được sử dụng trong ALTER USER <username> CREATEDB;lệnh cần khớp với người dùng cơ sở dữ liệu trong các tệp cài đặt Django của bạn. Trong trường hợp này, người đăng ban đầu, có người dùng như djangocâu trả lời ở trên.


2
Mặc dù OP đã sử dụng postgresql, nhưng nếu bạn đang sử dụng mysql, bạn sẽ gặp lỗi tương tự. Bạn có thể sửa nó cho mysql bằng: => GRANT ALL ON *. * TO django @ localhost; Ban đầu, tôi đã cố gắng chỉ GRANT CREATE ... nhưng sau đó không thể CHỌN hoặc DROP cơ sở dữ liệu đã tạo. Điều này về cơ bản làm cho người dùng của bạn trở thành một siêu người dùng, vì vậy hãy cẩn thận.
mightypile

1
Tôi đã thử nghiệm một chút và tìm thấy các đặc quyền toàn cầu tối thiểu là - Dữ liệu: CHỌN, CHERTN, CẬP NHẬT, XÓA, Cấu trúc: TẠO, THAY ĐỔI, INDEX, DROP, Quản trị viên: TÀI LIỆU THAM KHẢO. Không phải là một siêu người dùng, nhưng vẫn khá mạnh mẽ, vì vậy hãy thận trọng.
Scott

đối với trường hợp của tôi, tôi cấp tất cả các đặc quyền cho cơ sở dữ liệu thử nghiệm, đại loại như thế này:GRANT ALL PRIVILEGES ON test_my_db.* TO 'my_user'@'localhost';
Yacine Rouizi

17

Tôi đã tìm thấy giải pháp thú vị cho vấn đề của bạn.
Trong thực tế đối với MySQL, bạn có thể cấp các đặc quyền cho cơ sở dữ liệu không tồn tại.
Vì vậy, bạn có thể thêm tên 'test_finance' cho cơ sở dữ liệu thử nghiệm của mình trong cài đặt của mình:

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

khởi động MySQL shell với tư cách là người dùng root:

mysql -u root -p

và hiện cấp tất cả các đặc quyền cho cơ sở dữ liệu không tồn tại này trong MySQL:

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

Bây giờ Django sẽ bắt đầu thử nghiệm mà không có bất kỳ vấn đề.



4

Nếu cơ sở dữ liệu là mysql thì hai thay đổi này sẽ hoàn thành công việc.

1.Mở mysite / mysite / settings.py

Cài đặt cơ sở dữ liệu của bạn phải có khối TEST bổ sung như được hiển thị với projectname_test .

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

2. Nhập lệnh bên dưới bằng dấu nhắc lệnh mysql hoặc bàn làm việc mysql để cung cấp tất cả các quyền riêng tư cho người dùng được chỉ định trong settings.py

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

Bây giờ bạn có thể chạy python manage.py test polls.


Câu hỏi rõ ràng sử dụng Postgres là DBMS. Projectname_test sẽ liên quan đến cái gì?
mã-kobold

@ code-kobold 7, Có, nhưng tôi cũng có thể thấy lỗi tương tự trong mysql. Giá trị projectname_test được tham chiếu đến tên của dự án ex.in câu trả lời của tôi đó là myproject.
Chandan

1

Nếu bạn đang sử dụng docker-composenhững gì làm việc cho tôi là như sau:

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

hoặc là

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

Cài đặt của tôi trông như thế này:

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

docker-compose.ymlngoại hình của tôi như sau:

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

Trong trường hợp của tôi, các giải pháp GRANT PRIVILEGES không hoạt động với Python 3.7.2 , Django 2.1.7MySQL 5.6.23 ... Tôi không biết tại sao.

Vì vậy, tôi quyết định sử dụng SQLite làm cơ sở dữ liệu 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'),
        },
    }
}

Sau đó, xe TESTS chạy mà không gặp sự cố:

$ 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

Wow, kết hợp tất cả các câu trả lời ở đây với một chút tinh chỉnh cuối cùng đã đưa tôi đến một giải pháp hiệu quả cho việc soạn thảo docker, django và postgres ...

Đầu tiên, lệnh postgres được cung cấp bởi noufal valapra là không chính xác (hoặc có thể chỉ là không hiện tại), nên là:

ALTER USER docker WITH CREATEDB;

Trong trường hợp thiết lập docker-compose, điều này sẽ có trong tệp init.sql, đây là giao diện của tôi:

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

Sau đó, Dockerfile cho postgres trông như thế này:

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

Sau đó, cài đặt Django có mục này:

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

và docker-compose trông như thế này:

phiên bản: '3.6'

dịch vụ:

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

Có thể bạn đặt bài kiểm tra của mình ở chế độ treo hoặc làm công việc nền. Hãy thử với fglệnh trong bash shell.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.