Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pytest and Failed: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it

During invoking pytest from the shell I get the following output, because my test is stored in apps.business.metrics.tools.tests.py, and during import of the module

apps/business/metrics/widgets/employees/utilization.py

makes a live call to SQL during module invocation. This is done by

get_metric_columns('EmployeeUtilization', shapers=SHAPERS)

and pytest complaints:

➜ pytest
=========================================================================== test session starts ===========================================================================
platform linux -- Python 3.6.8, pytest-4.0.0, py-1.7.0, pluggy-0.8.0
Django settings: config.settings.local (from ini file)
rootdir: /home/dmitry/Projects/analytics/backend, inifile: pytest.ini
plugins: django-3.4.7, pylama-7.6.6, django-test-plus-1.1.1, celery-4.2.1
collected 60 items / 1 errors                                                                                                                                             

================================================================================= ERRORS ==================================================================================
__________________________________________________________ ERROR collecting apps/business/metrics/tools.tests.py __________________________________________________________
../../../.pyenv/versions/3.6.8/envs/cam/lib/python3.6/site-packages/py/_path/local.py:668: in pyimport
    __import__(modname)
apps/business/metrics/__init__.py:3: in <module>
    from .widgets import *  # noqa
apps/business/metrics/widgets/__init__.py:1: in <module>
    from . import help  # noqa
apps/business/metrics/widgets/help.py:1: in <module>
    from .employees.utilization import EmployeeSwarmUtilization
apps/business/metrics/widgets/employees/utilization.py:19: in <module>
    get_metric_columns('EmployeeUtilization', shapers=SHAPERS)
apps/business/metrics/tools.py:132: in get_metric_columns
    m = get_metric(metric, period=p, shapers=shapers)
apps/business/metrics/data/__init__.py:23: in get_metric
    return metrics[name](*args, **kwargs)
apps/business/metrics/data/abstract.py:441: in __init__
    self._to_dataframe(self.sql or self._ingest())
apps/business/metrics/data/abstract.py:472: in _to_dataframe
    source, connection, params=query_params, index_col=self.index
../../../.pyenv/versions/3.6.8/envs/cam/lib/python3.6/site-packages/pandas/io/sql.py:381: in read_sql
    chunksize=chunksize)
../../../.pyenv/versions/3.6.8/envs/cam/lib/python3.6/site-packages/pandas/io/sql.py:1413: in read_query
    cursor = self.execute(*args)
../../../.pyenv/versions/3.6.8/envs/cam/lib/python3.6/site-packages/pandas/io/sql.py:1373: in execute
    cur = self.con.cursor()
../../../.pyenv/versions/3.6.8/envs/cam/lib/python3.6/site-packages/django/db/backends/base/base.py:255: in cursor
    return self._cursor()
../../../.pyenv/versions/3.6.8/envs/cam/lib/python3.6/site-packages/django/db/backends/base/base.py:232: in _cursor
    self.ensure_connection()
E   Failed: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
========================================================================= 1 error in 2.43 seconds =========================================================================

Is there a way to handle such situation with pytest?

I understand I can convert the get_metric_columns('EmployeeUtilization', shapers=SHAPERS) into a partial func and change the implementation, but is there any other way around?

like image 637
DmitrySemenov Avatar asked Feb 13 '19 01:02

DmitrySemenov


People also ask

What does Pytest Mark Django_db do?

This is used to mark a test function as requiring the database. It will ensure the database is set up correctly for the test. Each test will run in its own transaction which will be rolled back at the end of the test. This behavior is the same as Django's standard TestCase class.

What database does Pytest use?

By default pytest-django will set up the Django databases the first time a test needs them. Once setup, the database is cached to be used for all subsequent tests and rolls back transactions, to isolate tests from each other.

What is Pytest fixture?

What Are Pytest Fixtures? Pytest fixtures are functions that can be used to manage our apps states and dependencies. Most importantly, they can provide data for testing and a wide range of value types when explicitly called by our testing software. You can use the mock data that fixtures create across multiple tests.


1 Answers

Solution:

import pytest


@pytest.mark.django_db
class TestExample:
    def test_one():
        ...

Assume that you've created a TestExample class inside your test file and it should be decorated with @pytest.mark.django_db. It should solve your problem.

like image 182
Ahsan Avatar answered Oct 05 '22 23:10

Ahsan