Open cameronmaske opened 6 years ago
Thanks for the detailed report.
Have you tried using the TEST
settings for this?
(see also https://github.com/pytest-dev/pytest-django/issues/559)
Can I add a +1 to this? Exactly the same issue and the same fix in conftest.py worked.
@mattaw
Have you seen my previous (unanswered) comment?
It is also not clear if you're using django_db_modify_db_settings
yourself (initially).
From the initial comment it appears like a lot of details are known already, so a PR based on that then would have made sense probably.
The same issue for me as well.
I am using below in rot conftest.py and by using test_context I want to override the DATABASE which is not happening. It still points to the project.settings settings file
@pytest.fixture(scope='session') def django_db_setup(test_context): settings.DATABASES['default'] = test_context.env_config.get('TEST_DATABASE')
@blueyed the initial reporter included a complete sample project.
any update on this would be appreciated? Without this we cannot point settings
to use an existing db as mentioned in the docs.
The fix mentioned above is not a working workaround for me, I get connection refused
when trying to connect to a postgres instance created by the testing.postgresql
library. But, at least Django is attempting to connect to the correct instance.
Same problem and the solution suggested here doesn't work.
I honestly don't think this will get fixed anytime soon, perhaps only if you create a PR yourself. There have been multiple issues opened over the years, 2017 was the first one. Basically they all experience the same issue, here are a few examples:
Maybe this is the only workaround that can work?
I have encountered this same issue when attempting to override the database settings the root conftest.py
. This is my workaround:
@pytest.fixture(scope="session", autouse=True)
def configure_test_db(
database_info: Dict[str, str],
) -> None:
"""
Add this to your conftest.py
"""
from django.conf import settings
from django.db import connections
# remove cached_property of connections.settings from the cache
del connections.__dict__["settings"]
# define settings to override during this fixture
settings.DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
**database_info,
}
}
# re-configure the settings given the changed database config
connections._settings = connections.configure_settings(settings.DATABASES)
# open a connection to the database with the new database config
# here the database is called 'default', but one can modify it to whatever fits their needs
connections["default"] = connections.create_connection("default")
The idea is to
@cached_property
of django.db.connections
. In Django 5, connections
is an instance of django.db.utils.ConnectionHandler
: srcdjango.conf.settings
and reflect those changes in django.db.connections
I have not tested this on a fixture that is function-scoped, i.e. does not set scope="session"
. It's possible something like this could work for using a database setup for a single test:
@pytest.fixture
def configure_test_db(
request: pytest.FixtureRequest, database_info: Dict[str, str],
) -> None:
from django.conf import settings
from django.db import connections
# remove cached_property of connections.settings from the cache
del connections.__dict__["settings"]
prev_db_setting = settings.DATABASES
def on_teardown() -> None:
settings.DATABASES = prev_db_setting
# define settings to override during this fixture
settings.DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
**database_info,
}
}
# re-configure the settings given the changed database config
connections._settings = connections.configure_settings(settings.DATABASES)
# open a connection to the database with the new database config
# here the database is called 'default', but one can modify it to whatever fits their needs
connections["default"] = connections.create_connection("default")
request.addfinalizer(on_teardown)
I suppose another way to do this is to change the patch the behavior of functools.cached_property
or of django.db.utils.ConnectionHandler
somewhere in https://github.com/pytest-dev/pytest-django/blob/master/pytest_django/fixtures.py.
To add to the previous explanation, since it was leaving the testing process dangling.
In my case, I wanted to use the same database without pytest creating a new one with the ‘test_’ prefix, so I set the test database name to match the default database.
Instead of creating a new fixture, I cleared the cache and recreated the connection within the django_db_setup
fixture, as recommended in the pytest-django documentation. This approach effectively resolved the issue for me.
@pytest.fixture(scope='session')
def django_db_setup():
# remove cached_property of connections.settings from the cache
del connections.__dict__["settings"]
settings.DATABASES['default'] = {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'name',
'USER': 'user',
'PASSWORD': 'password',
'HOST': 'host',
'PORT': '5432',
"TEST":
"NAME": 'name',
}
}
# re-configure the settings given the changed database config
connections._settings = connections.configure_settings(settings.DATABASES)
# open a connection to the database with the new database config
connections["default"] = connections.create_connection("default")
Hey all,
I ran into an issue trying to customize
django_db_modify_db_settings
.In my root level
conftest.py
I tried to make the tests run a sqlite in-memory database using (instead of my project settings.py which point to a postgres database).However, when the tests were run, any database interaction (Model's get, create, etc) would attempt to reach out to the original postgres database setting (aka
Doing a bit of digging, I think I can see what is happening.
When
setup_databases
(from here) is called, it in turn calls:get_unique_databases_and_mirrors
, which in turn calls:ConnectionHandler
which caches the databases from settings.After
ConnectionHandler
is initalized, which I believe is atdjango.setup()
it is fixed and stays pointed to whatever database settings it initalized with, even if they change down the line.My current work around to this, is to override the DATABASE settings in my own
pytest_configure
in my project'sconftest.py
AND to setDJANGO_SETTINGS_MODULE
there (e.g. nopytest.ini
). e.g.I believe setting the
DJANGO_SETTINGS_MODULE
there causes the_setup_django
inpytest_load_initial_conftests
to be skipped over, thus the it is called later, in the plugin'spytest_configure
.Resource:
Here is a sample project with it in action. It's a bit big, so here are the important bits.
I'm using Python:
3.6.6
and the following package versions...