2013-05-03 10 views
7

Z powodzeniem zainstalowałem rozszerzenie hstore i wszystko działa, gdy I syncdb. (Używam djorm-ext-hstore)Instalowanie rozszerzenia hstore w testach nosków django

Jednak nosa tworzy nową bazę danych tymczasowych do uruchamiania testów, a hstore nie jest zainstalowany w nim.

Muszę uruchomić CREATE EXTENSION HSTORE; na db testowy tuż przed nosem synchronizuje db, ale nie mogę znaleźć żadnych informacji, jak to zrobić.

Wszelkie pomysły?

+1

Możesz zaoszczędzić sobie wiele bólu, tworząc rozszerzenie w bazie danych postgres 'template1'. Następnie dowolna baza danych utworzona po tym będzie miała rozszerzenie HSTORE. – rantanplan

+0

rantaplan, które powinny być odpowiedzią! – 0atman

+0

Jest OK, zwykle unikam udzielania odpowiedzi w jednym wierszu. Cieszę się, że pomogłem. – rantanplan

Odpowiedz

3

Zakładam, że używasz django-nose. W tym przypadku należy utworzyć własną TestSuiteRunner:

from django.db import connections, DEFAULT_DB_ALIAS 
from django_nose import NoseTestSuiteRunner 

class MyTestSuiteRunner(NoseTestSuiteRunner): 
    def setup_databases(self): 
     result = super(MyTestSuiteRunner, self).setup_databases() 

     connection = connections[DEFAULT_DB_ALIAS] 
     cursor = connection.cursor() 
     cursor.execute('CREATE EXTENSION HSTORE') 

     return result 

Następnie w settings.py należy określić swoją testową zwyczaj biegacza:

TEST_RUNNER = 'path.to.my.module.MyTestSuiteRunner' 
+0

Dziękuję! Bez uruchamiania tego, widzę problem: Jeśli setup_databases() faktycznie tworzy tabele. Czy nie powinniśmy najpierw utworzyć rozszerzenia? – 0atman

+0

Masz prawdopodobnie rację, nie uruchomiłem tego kodu, żeby się upewnić. –

+1

Poinformuję cię, gdy go uruchomię. – 0atman

2

Od czasu mojej ostatniej odpowiedzi Django wycofał się i usunął sygnał pre_syncdb. Zaktualizowałem odpowiedź, aby uwzględnić nowsze wersje. Podstawowa mechanika jest identyczna dla nowszych wersji, ponieważ obie metody polegają na sygnałach i kodzie SQL, który wykonuje się tylko wtedy, gdy nie istnieje rozszerzenie HSTORE.

Django 1.8+

Ponieważ Django wprowadzono migracji DB pre_syncdb sygnały marked deprecated in 1.7 i completely removed in 1.9. Jednak wprowadzili nowy sygnał o nazwie pre_migrate, który może być używany w ten sam sposób.

""" 
This is an example models.py which contains all model definition. 
""" 
from django.dispatch import receiver 
from django.db import connection, models 
from django.db.models.signals import pre_syncdb 
import sys 

# The sender kwarg is optional but will be called for every pre_syncdb signal 
# if omitted. Specifying it ensures this callback to be called once. 
@receiver(pre_migrate, sender=sys.modules[__name__]) 
def setup_postgres_hstore(sender, **kwargs): 
    """ 
    Always create PostgreSQL HSTORE extension if it doesn't already exist 
    on the database before syncing the database. 
    Requires PostgreSQL 9.1 or newer. 
    """ 
    cursor = connection.cursor() 
    cursor.execute("CREATE EXTENSION IF NOT EXISTS hstore") 

# ...rest of your model definition goes here 
class Foo(models.Model): 
    # ...field definitions, etc. 

Django 1.6 + (oryginalna odpowiedź)

Moja sugestia jest użycie sygnału pre_syncdb hak.

Zobacz moją odpowiedź na inne question.

""" 
This is an example models.py which contains all model definition. 
""" 
from django.dispatch import receiver 
from django.db import connection, models 
from django.db.models.signals import pre_syncdb 
import sys 

# The sender kwarg is optional but will be called for every pre_syncdb signal 
# if omitted. Specifying it ensures this callback to be called once. 
@receiver(pre_syncdb, sender=sys.modules[__name__]) 
def setup_postgres_hstore(sender, **kwargs): 
    """ 
    Always create PostgreSQL HSTORE extension if it doesn't already exist 
    on the database before syncing the database. 
    Requires PostgreSQL 9.1 or newer. 
    """ 
    cursor = connection.cursor() 
    cursor.execute("CREATE EXTENSION IF NOT EXISTS hstore") 

# ...rest of your model definition goes here 
class Foo(models.Model): 
    # ...field definitions, etc. 

Sygnał pre_syncdb jest zwolniony przed utworzeniem tabeli modelu, dzięki czemu idealnie nadaje się do zapewnienia rozszerzenie jest zainstalowany, gdy baza danych test jest tworzone za każdym razem. IF NOT EXISTS zapewnia, że ​​PostgreSQL ignoruje polecenie, jeśli rozszerzenie jest już zainstalowane. Otrzymasz błąd, jeśli uruchomisz CREATE EXTENSION na istniejącym już rozszerzeniu.

Działa to w domyślnym środowisku testowym jednostki Django i najprawdopodobniej będzie działać w przypadku testów nosa Django.

Więcej informacji na temat sygnałów: https://docs.djangoproject.com/en/1.6/ref/signals/#management-signals

4

Ponadto można uruchomić polecenia SQL w migracji (Django 1.8):

class Migration(migrations.Migration): 

    # ... 

    operations = [ 
     migrations.RunSQL('create extension hstore;'), 
     # ... 
5

z Django 1.8:

from django.contrib.postgres.operations import HStoreExtension 

class Migration(migrations.Migration): 
    ... 

    operations = [ 
     HStoreExtension(), 
     ... 
    ] 

https://docs.djangoproject.com/en/1.8/ref/contrib/postgres/fields/#hstorefield

EDIT: po prostu pamiętać, że istnieje również JSONField który obsługuje (ONZ) rozrządowych JSON i już poszukiwaniu rolkach. HStoreExtension nie jest dla niego niezbędny. Wymaga Django> = 1.11 i Postgres> = 9.4.