2013-05-03 54 views
7

我已成功安裝hstore擴展,並且當我syncdb時,一切正常。 (我正在使用djorm-ext-hstore在django鼻子測試中安裝hstore擴展

但是,nose會創建一個新的臨時數據庫來運行測試,並且hstore未安裝在其中。

我需要在鼻子同步數據庫之前在測試數據庫上運行CREATE EXTENSION HSTORE;,但是我找不到有關如何執行此操作的任何信息。

任何想法?

+1

通過在'template1' postgres數據庫上創建擴展名,您可以節省很多痛苦。那麼之後創建的任何數據庫都將具有HSTORE擴展。 – rantanplan 2013-05-03 13:13:41

+0

rantaplan,這應該是答案! – 0atman 2013-05-04 11:24:13

+0

這很好,我通常避免給出單行答案。很高興我幫了忙。 – rantanplan 2013-05-04 11:58:09

回答

3

我假設你使用的是django-nose。在這種情況下,你應該創建自己的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 

然後在settings.py您應該指定您的自定義測試運行:

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

謝謝!沒有運行,我可以看到一個問題:如果setup_databases()實際創建表。我們不應該先創建擴展嗎? – 0atman 2013-05-03 10:37:11

+0

你可能是對的,我沒有運行這個代碼是肯定的。 – 2013-05-03 10:44:05

+1

我會在運行它時通知您。 – 0atman 2013-05-03 10:52:22

2

由於我上次的回答,Django棄用並刪除了pre_syncdb信號。我已經更新了答案以適應更新的版本。新版本的基本機制是相同的,因爲這兩種方法都依賴於信號以及僅當HSTORE擴展不存在時才執行的SQL代碼。

Django的1.8+

由於Django的引入DB遷移,pre_syncdb信號分別marked deprecated in 1.7completely removed in 1.9。然而,他們引入了一個名爲pre_migrate的新信號,可以用同樣的方法。

""" 
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+(原來的答案)

我的建議是使用pre_syncdb信號掛鉤。

在另一個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. 

創建模型表之前的pre_syncdb信號被觸發,非常適合以確保安裝擴展時被設定的測試數據庫每次上。如果已經安裝了擴展,IF NOT EXISTS可確保PostgreSQL忽略該命令。如果在已存在的擴展上運行CREATE EXTENSION,則會出現錯誤。

這適用於默認的Django單元測試框架,並且很可能適用於Django鼻子測試。

的信號更多信息: https://docs.djangoproject.com/en/1.6/ref/signals/#management-signals

4

您也可以在遷移運行SQL命令(Django的1。8):

class Migration(migrations.Migration): 

    # ... 

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