在django nose测试中安装hstore扩展

时间:2013-05-03 09:39:08

标签: python django postgresql nose hstore

我已经成功安装了hstore扩展,当syncdb时,一切正常。 (我正在使用djorm-ext-hstore

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

我需要在nose同步db之前在test db上运行CREATE EXTENSION HSTORE;,但我找不到有关如何执行此操作的任何信息。

有什么想法吗?

5 个答案:

答案 0 :(得分:26)

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

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

参考:How to create a new database with the hstore extension already installed?

答案 1 :(得分:6)

使用Django 1.8:

with qtrs(qtr) as (select level from dual connect by level <= 4)
, t1 as (
select region, product, year, q.qtr, month, sales, year*4+q.qtr qord
  from qtrs q
  left join one partition by (region, product, year)
    on q.qtr = one.qtr
)
select region
     , product
     , year
     , qtr
     , month
     , sales
     , round(avg(sales) over (partition by region, product, qord),2) avg_sale
     , round(avg(sales) over (partition by region, product
                              order by qord
                              range between 1 preceding
                                        and 1 preceding),2) prev_avg_sale
  from t1
 order by year, region, qtr, product;

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

编辑:请注意,还有一个JSONField处理(联合)json已经编组和内联搜索。 HStoreExtension不是必需的。需要Django&gt; = 1.11和Postgres&gt; = 9.4。

答案 2 :(得分:4)

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

class Migration(migrations.Migration):

    # ...

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

答案 3 :(得分: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'

答案 4 :(得分:3)

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

Django 1.8 +

由于Django引入了数据库迁移,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