Reputation: 10389
I would like pytest-django to install a Postgres extension when it creates a test database. I've been mucking with conftest.py to try to get this to work, but I'm stuck.
My conftest.py is at the top level of my project (same directory as manage.py), and contains:
from django.db import connection
import pytest_django
@pytest.fixture(scope='session')
def django_db_setup(*args, **kwargs):
pytest_django.fixtures.django_db_setup(*args, **kwargs)
cursor = connection.cursor()
cursor.execute("create extension pg_trgm")
But when I run it, I get:
_pytest.vendored_packages.pluggy.PluginValidationError: unknown hook 'pytest_django' in plugin <module 'conftest' from '/path/to/my/conftest.py'>
Upvotes: 5
Views: 3474
Reputation: 1635
I finally solved this using the django_test_environment
fixture.
import pytest
from django.db import connection
from django.db.models.signals import pre_migrate
from django.apps import apps
def _pre_migration(sender, app_config, **kwargs):
with connection.cursor() as cursor:
cursor.execute("CREATE EXTENSION IF NOT EXISTS pg_trgm;")
@pytest.fixture(autouse=True, scope="session")
def django_test_environment(django_test_environment):
pre_migrate.connect(_pre_migration, sender=apps.get_app_config("my_app"))
Upvotes: 2
Reputation: 630
An alternative solution would be to add the extension to the postgres template database. This means that all test databases created using the CREATE DATABASE
command will have the specified extension:
psql -d template1 -c 'CREATE EXTENSION IF NOT EXISTS pg_trgm;'
Now whenever pytest creates a test database, the pg_trgm
extension will be installed before migrations are run.
Upvotes: 0
Reputation: 4083
I've been trying to accomplish the same thing, and got this working (in conftest.py
):
@pytest.fixture(scope="session")
def django_db_setup(django_db_setup, django_db_blocker):
"""Test session DB setup."""
with django_db_blocker.unblock():
with connection.cursor() as cursor:
cursor.execute("CREATE EXTENSION IF NOT EXISTS citext;")
The key here is that you have to name your custom fixture with the same name as the standard pytest-django
fixture, but also include the default fixture as an argument. This is the way to run the standard fixture, rather than importing and calling it. I also found this failed unless I ran django_db_blocker.unblock()
.
Upvotes: 1
Reputation: 157
You could use the pre_migrate
signals. For example:
from django.db.models.signals import pre_migrate
from django.apps import apps
def app_pre_migration(sender, app_config, **kwargs):
cur = connection.cursor()
cur.execute('CREATE EXTENSION IF NOT EXISTS pg_trgm;')
pre_migrate.connect(app_pre_migration, sender=apps.get_app_config('app'))
I hope this could help you.
Upvotes: 8