代码之家  ›  专栏  ›  技术社区  ›  Krumelur

在Django/sqlite中更改文本\u工厂

  •  6
  • Krumelur  · 技术社区  · 14 年前

    sqlite中的解决方案是将文本工厂更改为: lambda x: unicode(x, "utf-8", "ignore")

    然而,我不知道如何告诉Django模型司机这个。

    我得到的例外是:

    'Could not decode to UTF-8 column 'Text' with text' in /var/lib/python-support/python2.5/django/db/backends/sqlite3/base.py in execute

    不知何故,我需要告诉sqlite驱动程序不要尝试将文本解码为UTF-8(至少不使用标准算法,但它需要使用我的fail-safe变体)。

    5 回复  |  直到 14 年前
        1
  •  9
  •   zifot    14 年前

    sqlite的解决方案是改变 将文本转换为如下内容: lambda x:unicode(x,“utf-8”,

    你试过了吗

    from django.db import connection
    connection.connection.text_factory = lambda x: unicode(x, "utf-8", "ignore")
    

    在运行任何查询之前?

        2
  •  2
  •   EMS    10 年前

    当您无法控制如何将文本添加到sqlite数据库并且它可能不在utf-8中时使用。 当然,这里使用的编码可能不正确,但至少应用程序不会崩溃。

    import types
    from django.db.backends.sqlite3.base import DatabaseWrapper
    
    def to_unicode( s ):
        ''' Try a number of encodings in an attempt to convert the text to unicode. '''
        if isinstance( s, unicode ):
            return s
        if not isinstance( s, str ):
            return unicode(s)
    
        # Put the encodings you expect here in sequence.
        # Right-to-left charsets are not included in the following list.
        # Not all of these may be necessary - don't know.
        encodings = (
            'utf-8',
            'iso-8859-1', 'iso-8859-2', 'iso-8859-3',
            'iso-8859-4', 'iso-8859-5',
            'iso-8859-7', 'iso-8859-8', 'iso-8859-9',
            'iso-8859-10', 'iso-8859-11',
            'iso-8859-13', 'iso-8859-14', 'iso-8859-15',
            'windows-1250', 'windows-1251', 'windows-1252',
            'windows-1253', 'windows-1254', 'windows-1255',
            'windows-1257', 'windows-1258',
            'utf-8',     # Include utf8 again for the final exception.
        )
        for encoding in encodings:
            try:
                return unicode( s, encoding )
            except UnicodeDecodeError as e:
                pass
        raise e
    
    if not hasattr(DatabaseWrapper, 'get_new_connection_is_patched'):
        _get_new_connection = DatabaseWrapper.get_new_connection
        def _get_new_connection_tolerant(self, conn_params):
            conn = _get_new_connection( self, conn_params )
            conn.text_factory = to_unicode
            return conn
    
        DatabaseWrapper.get_new_connection = types.MethodType( _get_new_connection_tolerant, None, DatabaseWrapper )
        DatabaseWrapper.get_new_connection_is_patched = True
    
        3
  •  0
  •   maersu    14 年前

    str function 来自Django:

    smart_str(s, encoding='utf-8', strings_only=False, errors='strict')
    

    smart_unicode(s, encoding='utf-8', strings_only=False, errors='strict')
    
        4
  •  0
  •   Milla Well    11 年前

    看来,这个问题经常出现,许多人对此非常感兴趣(因为这个问题有一千多个观点和相当多的赞成票)

    我检查了django sqlite3连接器,并将str转换直接添加到 get_new_connection(...)

    def get_new_connection(self, conn_params):
        conn = Database.connect(**conn_params)
        conn.create_function("django_date_extract", 2, _sqlite_date_extract)
        conn.create_function("django_date_trunc", 2, _sqlite_date_trunc)
        conn.create_function("django_datetime_extract", 3, _sqlite_datetime_extract)
        conn.create_function("django_datetime_trunc", 3, _sqlite_datetime_trunc)
        conn.create_function("regexp", 2, _sqlite_regexp)
        conn.create_function("django_format_dtdelta", 5, _sqlite_format_dtdelta)
        conn.text_factory = str
        return conn
    

    它似乎可以正常工作,而且不必逐个检查每个请求中的unicode问题。是否应该考虑将此添加到django代码(?),因为我不建议任何人实际手动修改django后端代码。。。

        5
  •  0
  •   Nader Alexan    10 年前
    from django.db import connection
    connection.cursor()
    connection.connection.text_factory = lambda x: unicode(x, "utf-8", "ignore")
    

    在我的特定情况下,我需要设置connection.connection.text\u factory=str

        6
  •  0
  •   ZF007    4 年前