Django 从 shell 启动时 QuerySet extra 到 PostgreSQL 的 UnicodeEncodeError

0 投票
1 回答
979 浏览
提问于 2025-04-16 16:52

大家好,

我在两台机器上使用Django 1.2.5和Python 2.6:一台是Ubuntu 11.04本地开发机,另一台是Debian Lenny远程服务器。我在这两台机器上都使用django-fts和PostgreSQL(数据库是远程的,并且两台机器使用的是同一个数据库)来进行全文搜索查询。有趣的是,我在本地机器上可以正常使用包含俄文字符的fts查询,但在远程服务器上却出现了UnicodeEncodeError的错误。

在django-fts的Postgre后端,我发现了这段代码:

    ts_query = "plainto_tsquery('%s','%s')" % (self.language, unicode(query).replace("'", "''"))
    where = '%s @@ %s' % (qn(self.vector_field.column), ts_query)
    select = {}
    order = []
    if rank_field is not None:
        select[rank_field] = 'ts_rank(%s.%s, %s, %d)' % (qn(self.model._meta.db_table), qn(self.vector_field.column), ts_query, rank_normalization)
        order = ['-%s' % rank_field]
    return qs.extra(select=select, where=[where], order_by=order)`

这里的查询包含了u'\u0430'或u"а"(西里尔字母),所以它在utf-8编码上是没问题的。

错误出现在django/db/models/sql/compiler.py的第489行,当我试图从extras组装查询时:

result.append('(%s)' % str(col))

所以,我尝试了所有关于编码和解码的操作。两个电脑上的LANG变量都是"ru_RU.UTF-8",在settings.py中也设置了DEFAULT_CHARSET。现在我没有其他想法了。有没有人能帮帮我?

更新:我刚发现我的应用在两台电脑上执行的方式是一样的。不同之处在于从命令行执行(python manage.py runserver localhost:8000)和从Eclipse的pydev环境中以调试模式启动的方式。那么,有人能告诉我手动启动和pydev调试启动在编码问题上是否有区别吗?

谢谢大家。

彼得

1 个回答

1

在你例子里的所有字符串前面加一个 u''。
比如像这样:u'ts_rank(%s.%s, %s, %d)' % (...)
而且用 % 来插入变量而不进行数据库转义是很不安全的。

撰写回答