我已经成功安装了hstore扩展,当syncdb
时,一切正常。 (我正在使用djorm-ext-hstore)
但是,nose会创建一个新的临时数据库来运行测试,并且没有安装hstore。
我需要在nose同步db之前在test db上运行CREATE EXTENSION HSTORE;
,但我找不到有关如何执行此操作的任何信息。
有什么想法吗?
答案 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引入了数据库迁移,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