加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

postgresql – 异常中的SQLAlchemy Unicode问题

发布时间:2020-12-13 16:14:12 所属栏目:百科 来源:网络整理
导读:我正在开发一个带有postgres / SQLAlchemy / Flask-Admin的Flask应用程序.但是,在Admin界面中,由于unicode(exc)引发UnicodeDecodeError,因此无法报告包含Unicode字母的任何DB错误. 我能够找到问题到 sqlalchemy.exc class StatementError(SQLAlchemyError):
我正在开发一个带有postgres / SQLAlchemy / Flask-Admin的Flask应用程序.但是,在Admin界面中,由于unicode(exc)引发UnicodeDecodeError,因此无法报告包含Unicode字母的任何DB错误.

我能够找到问题到sqlalchemy.exc

class StatementError(SQLAlchemyError):
    ...
    def __unicode__(self):
        return self.__str__()

并通过以下方式重现问题:

class A(Base):
    __tablename__="a"
    id = Column(Integer,primary_key=True)
    name = Column(String)
    name2 = Column(String,nullable=False)

session = Session()
a = A(name=u"?????")
session.add(a)

try:
    session.commit()
except Exception as e:
    print(repr(e))
    print("------------------")
    print(unicode(e))

哪个回报:

ProgrammingError('(psycopg2.ProgrammingError) column "name" of relation "a" does not existnLINE 1: INSERT INTO a (name,name2) VALUES ('xd7xa2xd7x91xd7xa8xd7x99xd7xaa',NULL) RETURNING...n                       ^n',)
------------------
Traceback (most recent call last):
  File "test.py",line 27,in <module>
    print(unicode(e))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd7 in position 118: ordinal not in range(128)

我目前通过用从utf-8解码的类替换相关的异常来解决它.但是,这是一个可怕的黑客攻击,我正在寻找一个合适的解决方案:

>有没有办法配置SQLAlchemy自动解码收到的错误消息?
>有没有办法配置Postgres以拉丁编码输出消息(不太有利,但可以接受)
>有没有办法让unicode尝试用utf-8而不是ascii / latin进行解码?
>有什么办法可以解决它吗?

(这个问题只与Python2有关.在Python3中,上面的代码可以工作.我相信这是因为默认编码是utf-8)

我实际上认为从您的应用程序修补SQLAlchemy是正确的合理清洁解决方案.原因如下:

>您已经确定了一些通常被认为是SQLAlchemy中的错误的内容.
>您可以编写一个对SQLAlchemy当前使用的所有情况都行为相同的补丁.也就是说,您的补丁不会破坏现有代码
>概率非常高,即使修复SQLAlchemy,您的补丁也将是无害的.
>进行此更改可以减少SQLAlchemy错误在整个代码中对解决方案的影响,例如更改可能打印异常的每个位置.
>更改PostGres以返回latin1编码实际上无济于事,因为python正在使用ascii编码,这在给定latin1字符串时会产生相同的错误.此外,更改PostGres以返回latin1错误可能涉及更改连接编码;这可能会为unicode数据带来问题.

这是一个简单的程序,可以修补sqlalchemy.exc.StatementError并测试补丁.如果你想要甚至可以尝试生成包括unicode在内的异常,请将其转换为unicode,并且只有在引发UnicodeDecodeError时才应用补丁.如果您这样做,当sqlalchemy修复问题时,您的补丁将自动停止应用.

# -*- coding: utf-8 -*-
from sqlalchemy.exc import StatementError

def statement_error_unicode(self):
    return unicode(str(self),'utf-8')
# See <link to sqlalchemy issue>; can be removed once we require a
# version of sqlalchemy with a fix to that issue
StatementError.__unicode__ = statement_error_unicode

message = u'Sqlalchemy unicode                        

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读