pytest-dev / pytest-django

A Django plugin for pytest.
https://pytest-django.readthedocs.io/
Other
1.39k stars 344 forks source link

RuntimeError: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it. #1011

Closed Sirneij closed 2 years ago

Sirneij commented 2 years ago

I keep getting this error RuntimeError: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it. while running my tests using this command: py.test -n auto --disable-socket -W error::RuntimeWarning --cov=src --cov-report=html tests/

Based on your recommendation, my conftest.py has the following content:

import pytest

from core.models import GenericSettings
from tests.core.test_models import GenericSettingsFactory

@pytest.fixture
def generic_settings() -> GenericSettings:
    # return the GenericSettingsFactory (factoryboy)
    return GenericSettingsFactory()

@pytest.fixture(autouse=True)
def enable_db_access_for_all_tests(db):
    pass

pytest.ini has the following as content:

[pytest]
norecursedirs = scripts node_modules py-requirements webpack .* {args}
DJANGO_SETTINGS_MODULE=dynamic_settings.settings.dev
pythonpath = src tests

Part of the traceback is:

...
src/ass/tasks/com.py:12: in <module>
    from com.tasks import com_send_email_task
src/com/tasks/__init__.py:2: in <module>
    from .sending import *  # noqa
src/com/tasks/sending.py:23: in <module>
    generic_settings = GenericSettings.load()
src/admin/models.py:433: in load
    obj, _ = cls.objects.get_or_create(id=1)
virtualenv/lib/python3.9/site-packages/django/db/models/manager.py:85: in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
virtualenv/lib/python3.9/site-packages/django/db/models/query.py:581: in get_or_create
    return self.get(**kwargs), False
virtualenv/lib/python3.9/site-packages/django/db/models/query.py:431: in get
    num = len(clone)
virtualenv/lib/python3.9/site-packages/django/db/models/query.py:262: in __len__
    self._fetch_all()
virtualenv/lib/python3.9/site-packages/django/db/models/query.py:1324: in _fetch_all
    self._result_cache = list(self._iterable_class(self))
virtualenv/lib/python3.9/site-packages/django/db/models/query.py:51: in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
virtualenv/lib/python3.9/site-packages/django/db/models/sql/compiler.py:1173: in execute_sql
    cursor = self.connection.cursor()
virtualenv/lib/python3.9/site-packages/django/utils/asyncio.py:33: in inner
    return func(*args, **kwargs)
virtualenv/lib/python3.9/site-packages/django/db/backends/base/base.py:259: in cursor
    return self._cursor()
virtualenv/lib/python3.9/site-packages/django/db/backends/base/base.py:235: in _cursor
    self.ensure_connection()
E   RuntimeError: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it.

The model GenericSettings which was highlighted by the traceback is a singleton with the following content:

from django.contrib.postgres.fields import ArrayField
from django.db import models

def get_default_vpn_provider() -> list:
    return ["Access", "CyberGhost", "ExpressVPN"]

class SettingsBaseModel(models.Model):
    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        self.pk = 1
        super(SettingsBaseModel, self).save(*args, **kwargs)

    def delete(self, *args, **kwargs):
        pass

    @classmethod
    def load(cls):
        obj, _ = cls.objects.get_or_create(pk=1)
        return obj

class GenericSettings(SettingsBaseModel):
    ACCESS = "Access"
    CYBERGHOST = "CyberGhost"
    EXPRESSVPN = "ExpressVPN"

    VPN_PROVIDERS = [
        (ACCESS, "Access"),
        (CYBERGHOST, "CyberGhost"),
        (EXPRESSVPN, "ExpressVPN"),
    ]

    vpn_providers = models.CharField(
        max_length=20, choices=VPN_PROVIDERS, default=ACCESS
    )
    default_vpn_provider = ArrayField(
        models.CharField(max_length=20), default=get_default_vpn_provider
    )

How can I get rid of these errors?

Preliminaries:

============================= test session starts ==============================
platform linux -- Python 3.9.12, pytest-7.1.2, pluggy-1.0.0
django: settings: dynamic_settings.settings.dev (from ini)
rootdir: /home/sirneij/Documents/Projects/dynamic_settings, configfile: pytest.ini
plugins: forked-1.4.0, django-4.5.2, socket-0.5.1, cov-3.0.0, Faker-13.6.0, xdist-2.5.0, django-webtest-1.9.10, celery-4.4.7
collecting 0 items / 33 errors
Sirneij commented 2 years ago

Since no comment is forthcoming, let me close this. I have already fixed the issue.

kingbuzzman commented 2 years ago

@Sirneij Would be nice to know what you did to solve it..