我已成功安裝hstore擴展,並且當我syncdb
時,一切正常。 (我正在使用djorm-ext-hstore)在django鼻子測試中安裝hstore擴展
但是,nose會創建一個新的臨時數據庫來運行測試,並且hstore未安裝在其中。
我需要在鼻子同步數據庫之前在測試數據庫上運行CREATE EXTENSION HSTORE;
,但是我找不到有關如何執行此操作的任何信息。
任何想法?
我已成功安裝hstore擴展,並且當我syncdb
時,一切正常。 (我正在使用djorm-ext-hstore)在django鼻子測試中安裝hstore擴展
但是,nose會創建一個新的臨時數據庫來運行測試,並且hstore未安裝在其中。
我需要在鼻子同步數據庫之前在測試數據庫上運行CREATE EXTENSION HSTORE;
,但是我找不到有關如何執行此操作的任何信息。
任何想法?
我假設你使用的是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'
這是一個不是問題的問題:要解決這個問題是最好的方法應用hstore擴展名的默認數據庫,template1
psql -d template1 -c 'create extension hstore;'
參考:How to create a new database with the hstore extension already installed?
由於我上次的回答,Django棄用並刪除了pre_syncdb
信號。我已經更新了答案以適應更新的版本。新版本的基本機制是相同的,因爲這兩種方法都依賴於信號以及僅當HSTORE擴展不存在時才執行的SQL代碼。
由於Django的引入DB遷移,pre_syncdb
信號分別marked deprecated in 1.7和completely 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.
我的建議是使用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
您也可以在遷移運行SQL命令(Django的1。8):
class Migration(migrations.Migration):
# ...
operations = [
migrations.RunSQL('create extension hstore;'),
# ...
使用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
編輯:只是注意,也有一個JSONField它處理JSON已經和在線搜索(UN)編組。 HStoreExtension不是必需的。需要Django> = 1.11和Postgres> = 9.4。
通過在'template1' postgres數據庫上創建擴展名,您可以節省很多痛苦。那麼之後創建的任何數據庫都將具有HSTORE擴展。 – rantanplan 2013-05-03 13:13:41
rantaplan,這應該是答案! – 0atman 2013-05-04 11:24:13
這很好,我通常避免給出單行答案。很高興我幫了忙。 – rantanplan 2013-05-04 11:58:09