2012-11-05 44 views
3

我在Heroku(雪松堆栈)上部署了一个Django(v 1.3.3)项目。它使用推荐的dj_database_url来配置settings.DATABASES。一切都很好(到这一点)。Heroku上的django-hstore

但是,我想开始使用django-hstore作为应用程序的一部分。根据该文件,你必须在settings.py更改数据库引擎:

'ENGINE': 'django_hstore.postgresql_psycopg2', 

其结果是,在我的settings.py文件,我做了以下内容:

DATABASES = {'default': dj_database_url.config()} 
DATABASES['default']['ENGINE'] = 'django_hstore.postgresql_psycopg2' 

一切正常对我来说,在当地很好。我的模型有hstore领域工作很好(价值是字典)。

然而,当我部署到Heroku上,数据库引擎被重置/重载:

ENGINE: 'django.db.backends.postgresql_psycopg2' 

。在调试它一个尝试,我已经把打印在我的设置文件中设置了发动机之后。然后,我运行的bash:

heroku run bash 

然后:

python myapp/manage.py shell 

当我运行这一点,我的print语句显示我正确的(期望)数据库所需的发动机(django_hstore.postgresql_psycopg2)设置。但是,如果我再做:

from django.conf import settings 
print settings.DATABASES 

我可以看到数据库引擎不再django_hstore,但重新设置为正常(非hstore)值。如果我输入我的车型之一,做一个GET来加载一个对象,在hstore字段中的值是一个字符串,任何试图访问一个键会引发和错误:

TypeError: string indices must be integers, not str 

请记住这个工作可以在当地找到。但是,在部署到heroku之后,任何以字典访问值的尝试都会抛出上面的TypeError。

我的问题是:

  • 有谁知道为什么我的引擎是越来越重写?如果是这样,我该如何解决这个问题?

  • 有另一种方式来使用hstore领域和Django 1.3.3,可能不要求有改变发动机(因此是多一点的Heroku友好)
+0

你是怎么结束工作了?我正在使用HStore w/Django&Heroku,并在跳入它之前对此陷阱保持警惕。 –

回答

2

SQLAlchemy 0.8包括可用于创建custom model的实用方法,用于处理Python dict和Postgres hstore之间的转换。

from django.db import models 
from sqlalchemy.dialects.postgresql.hstore import _parse_hstore, _serialize_hstore 

class HStoreField (models.TextField): 
    __metaclass__ = models.SubfieldBase 

    def __init__(self, *args, **kwargs): 
     super(HStoreField, self).__init__(*args, **kwargs) 

    def to_python(self, value): 
     if value is None: 
      return None 
     if isinstance(value, dict): 
      return value 
     return _parse_hstore(value) 

    def get_db_prep_save(self, value, connection): 
     if value is None: 
      return None 
     if isinstance(value, str): 
      return value 
     return _serialize_hstore(value) 

    def db_type (self, connection): 
     return "hstore" 

这种模式是便携式的,但如果你想运行基于hstore键或值查询,你必须把它们写在原始SQL。

我使用的SQLite内存数据库运行测试,只要您使用text型非PostgreSQL的后端工作正常:

def db_type (self, connection): 
     from django.db import connection 
     if connection.settings_dict['ENGINE'] == \ 
      'django.db.backends.postgresql_psycopg2': 
      return "hstore" 
     else: 
      return "text" 
+0

为什么它值得我在Django 1.5中使用这个变体,并且它似乎正在工作。我不得不添加一个咒语,以使其与南方顺利合作。 – pdc

1

https://github.com/niwibe/djorm-ext-hstore

貌似这个包是最初是django-hstore的一个分支,包含相同的功能,但已更新为不再需要自定义数据库后端,这似乎可以缓解您的问题。 (请注意,其中一些查询语法已更改)。

作为奖励,回购维持得比您连接到的original django-hstore要近得多,这在多年以来一直没有被触动......可怕的。

+0

的确如此。 django-hstore似乎不再被维护,而djorm-ext-hstore活跃。 – chhantyal