8

我已经成功安装了 hstore 扩展,并且当我syncdb. (我正在使用djorm-ext-hstore

但是,nose 创建了一个新的临时数据库来运行测试,并且没有安装 hstore。

我需要CREATE EXTENSION HSTORE;在鼻子同步数据库之前在测试数据库上运行,但我找不到有关如何执行此操作的任何信息。

有任何想法吗?

4

6 回答 6

26

这不是问题:解决此问题的最佳方法是在默认数据库上应用 hstore 扩展,template1

psql -d template1 -c 'create extension hstore;'

参考:如何创建一个已经安装了 hstore 扩展的新数据库?

于 2013-05-03T23:32:14.990 回答
8

使用 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。

于 2015-09-02T16:45:38.090 回答
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'
于 2013-05-03T10:25:33.420 回答
4

自从我上次回答以来,Django 弃用并删除了pre_syncdb信号。我已经更新了答案以适应更新的版本。新版本的基本机制是相同的,因为这两种方法都依赖于信号和仅在 HSTORE 扩展不存在时执行的 SQL 代码。

姜戈 1.8+

由于 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.

Django 1.6+(原始答案)

我的建议是使用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

于 2014-05-13T08:16:01.317 回答
4

您也可以在迁移中运行 sql 命令(Django 1.8):

class Migration(migrations.Migration):

    # ...

    operations = [
        migrations.RunSQL('create extension hstore;'),
        # ...
于 2015-06-05T13:15:48.697 回答
1

这对我 有用 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'
于 2020-12-27T05:44:51.847 回答