我已经成功安装了 hstore 扩展,并且当我syncdb
. (我正在使用djorm-ext-hstore)
但是,nose 创建了一个新的临时数据库来运行测试,并且没有安装 hstore。
我需要CREATE EXTENSION HSTORE;
在鼻子同步数据库之前在测试数据库上运行,但我找不到有关如何执行此操作的任何信息。
有任何想法吗?
我已经成功安装了 hstore 扩展,并且当我syncdb
. (我正在使用djorm-ext-hstore)
但是,nose 创建了一个新的临时数据库来运行测试,并且没有安装 hstore。
我需要CREATE EXTENSION HSTORE;
在鼻子同步数据库之前在测试数据库上运行,但我找不到有关如何执行此操作的任何信息。
有任何想法吗?
这不是问题:解决此问题的最佳方法是在默认数据库上应用 hstore 扩展,template1
psql -d template1 -c 'create extension hstore;'
使用 Django 1.8(现在已经过时,但在 3.2 中仍然存在):
from django.contrib.postgres.operations import HStoreExtension
class Migration(migrations.Migration):
...
operations = [
HStoreExtension(),
...
]
https://docs.djangoproject.com/en/3.2/ref/contrib/postgres/fields/#hstorefield
编辑:请注意,还有一个JSONField已经处理(un)编组 json 和内联搜索。HStoreExtension 不是它所必需的。需要 Django >=1.11 和 Postgres >=9.4。
我假设您正在使用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'
自从我上次回答以来,Django 弃用并删除了pre_syncdb
信号。我已经更新了答案以适应更新的版本。新版本的基本机制是相同的,因为这两种方法都依赖于信号和仅在 HSTORE 扩展不存在时执行的 SQL 代码。
由于 Django 引入了 DB 迁移,pre_syncdb
信号在 1.7 中被标记为弃用,并在 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_migrate
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
信号挂钩。
请参阅我对另一个问题的回答。
"""
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;'),
# ...
这对我 有用 https://gist.github.com/smcoll/bb2533e4b53ae570e11eb2ab011b887b
from django.db.backends.base import creation
from django.test.runner import DiscoverRunner
class CustomDiscovererRunner(DiscoverRunner):
def setup_databases(self, **kwargs):
def wrap_create_test_db(function):
def decorated_create_test_db(self, verbosity, autoclobber, keepdb):
test_database_name = function(self, verbosity, autoclobber, keepdb)
self.connection.close()
self.connection.settings_dict["NAME"] = test_database_name
cursor = self.connection.cursor()
cursor.execute('CREATE EXTENSION IF NOT EXISTS hstore')
return test_database_name
return decorated_create_test_db
creation.BaseDatabaseCreation._create_test_db = wrap_create_test_db(
creation.BaseDatabaseCreation._create_test_db
)
return super(CustomDiscovererRunner, self).setup_databases(**kwargs)
设置.py
TEST_RUNNER = 'my_project.settings_test.CustomDiscovererRunner'