2012-11-05 45 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