3

Heroku (cedar stack) にデプロイされた Django (v 1.3.3) プロジェクトがあります。settings.DATABASES の構成には、推奨される dj_database_url を使用します。すべてがうまく機能します(この時点まで)。

ただし、アプリケーションの一部に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

これを実行すると、印刷ステートメントは、目的のエンジン (django_hstore.postgresql_psycopg2) を使用した正しい (目的の) データベース設定を表示します。ただし、次の場合:

from django.conf import settings
print settings.DATABASES

データベース エンジンが django_hstore ではなく、通常の (非 hstore) 値に戻っていることがわかります。また、モデルの 1 つをインポートして get を実行してオブジェクトをロードすると、hstore フィールドの値は文字列になり、キーにアクセスしようとすると次のエラーが発生します。

TypeError: string indices must be integers, not str

この作品はローカルで見つけることに注意してください。しかし、heroku にデプロイした後、辞書として値にアクセスしようとすると、上記の TypeError がスローされます。

私の質問は次のとおりです。

  • 私のエンジンがオーバーライドされている理由を誰か知っていますか? もしそうなら、どうすればこれを修正できますか?

また

  • エンジンを変更する必要がない可能性がある Django 1.3.3 で hstore フィールドを使用する別の方法はありますか (したがって、もう少し Heroku フレンドリーになります)
4

3 に答える 3

2

SQLAlchemy 0.8には、Pythonと Postgres間の変換を処理するためのカスタム モデルを作成するために使用できるユーティリティ メソッドが含まれています。dicthstore

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 で記述する必要があります。

textテストを実行するために SQLite インメモリ データベースを使用します。これは、 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"
于 2013-02-24T03:20:01.530 に答える
1

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

このパッケージはもともと django-hstore のフォークであり、同じ機能が含まれているようですが、問題を軽減するように見えるカスタム データベース バックエンドを必要としないように更新されています。(一部のクエリ構文が変更されていることに注意してください)。

おまけとして、レポは、リンク先の元の django-hstoreよりもずっと最近維持されています。これは何年も触れられていません...怖いです。

于 2013-03-15T04:52:21.923 に答える
1

django_hstore の新しいバージョン 1.2.1 がリリースされました。

pip 経由でアップグレードし、新しい公式の django-hstore github リポジトリを確認してください: https://github.com/djangonauts/django-hstore

于 2014-02-28T14:53:38.583 に答える