ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python-Heroku上的django-hstore

2019-10-31 17:57:17  阅读:290  来源: 互联网

标签:hstore heroku psycopg2 python django


我已经在Heroku(雪松堆栈)上部署了一个Django(v 1.3.3)项目.它使用推荐的dj_database_url来配置settings.DATABASES.一切都很好(到目前为止).

但是,我想开始将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)值.而且,如果我导入一个模型并执行加载对象的操作,则hstore字段中的值是一个字符串,任何访问键的尝试都会抛出错误:

TypeError: string indices must be integers, not str

请记住,此作品可在本地找到.但是,在部署到heroku之后,任何尝试访问值作为字典的尝试都将抛出TypeError.

我的问题是:

>有人知道为什么我的引擎被覆盖吗?如果是这样,我该如何解决?

要么

>还有另一种方法可以在Django 1.3.3中使用hstore字段,该方法可能不需要更改引擎(因此对Heroku更加友好)

解决方法:

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内存数据库来运行测试,只要您将文本类型用于非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"

标签:hstore,heroku,psycopg2,python,django
来源: https://codeday.me/bug/20191031/1977653.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有