美文网首页
Python连接SQLServer之UnicodeDecodeE

Python连接SQLServer之UnicodeDecodeE

作者: 董书广 | 来源:发表于2017-07-14 12:36 被阅读0次

    缘由:由于工作原因,需要从SQLServer数据库中同步一部分数据到mongodb中,用于建模,运算。

    开发环境:Windows,Python3.5.2
    开发工具:pycharm2017.1.4
    连接SQLServer所用module:pymssql
    目标数据库版本:SQLServer2008 编码为GBK

    具体情况:
    开始连接数据库的代码如下

        # 连接数据库,获取游标
        @staticmethod
        def get_sql_connect(host, user, password, database, charset):
            if host is None or user is None or password is None or database is None:
                raise ConnectionError('连接数据库的必要参数为空')
            if charset is None:
                charset = 'utf8'
            sql_conn = pymssql.connect(
                host=host,
                user=user,
                password=password,
                database=database,
                charset=charset
            )
            return sql_conn
    
    conn = SynchronizeData.get_sql_connect('.', 'sa', '712604', 'test', 'GB18030')
    

    这里在连接的时候传入charset='GBK',因为目标数据库编码是GBK,在python中如果不带这个参数那么查询出来的中文将会显示乱码。带上这个参数之后一切看起来没毛病,在执行了一段时间之后发现会出现UnicodeDecodeError:'gbk'codec can't decode byte 0x81 in position 18:illegal multibyte sequen这样的异常。当时也google了好久,后来找了个靠谱的方案说是因为GBK的字符不多,于是把GBK换成了GB18030问题得到解决。

    但是在导入某个表的时候发现此时GB18030也报了上面类似的异常。定位到数据以后该字段的类型类text,里面存储的是一篇文章,初步估计是里面的内容在python中查询之后转Unicode发生了莫名其妙的错误。此时继续在google上搜索,绝大部分说这个异常的情况都是在python中打开文件,然后解决办法是在打开文件的代码中加上coding='utf-8',然而我在连接数据库的时候不过不带charset这个参数就会发生中文乱码,带了吧,就会发生那个异常。本来都打算把数据导出成excel,然后通过mongodbimport去导入了,奈何数据量有点大,昨天这个导出的过程持续了一天也不过导出了一半不到的数据。

    今天早上到公司的时候不死心的又在看这个问题。忽然想试下把该字段的类型改成ntext的形式不知道行不行。(SQLServer中有varchar和nvarchar,text和ntext之分,不知道的请另行百度)。把字段的类型改了还是继续采用上面的连接,发现代码是不报错了,但是该字段中的所有中文却消失了,只留下了数字和符号。这很显然又不行的,于是我试验了下面的代码
    # 连接数据库,获取游标
    @staticmethod
    def get_sql_connect(host, user, password, database):
    if host is None or user is None or password is None or database is None:
    raise ConnectionError('连接数据库的必要参数为空')
    sql_conn = pymssql.connect(
    host=host,
    user=user,
    password=password,
    database=database
    )
    return sql_conn
    conn = SynchronizeData.get_sql_connect('.', 'sa', '712604', 'test')

    激动人心的事情发生了:中文不乱码了,而且字段中的内容也没丢失。问题到这里似乎就可以解决了。接下来的情况就因人而异了:
    在修改表字段的时候发现有的字段有索引,导致修改类型失败。于是问题转变成能不能在查询的时候把类型给替换掉。很显然SQLserver还是可以完成这样的功能的: CAST()
    于是把我查询的select * from table 改成 select cast(中文内容的字段 as ntext) from table (如果该字段是varchar则 as后面是 nvarchar),问题到这才算完美解决

    相关文章

      网友评论

          本文标题:Python连接SQLServer之UnicodeDecodeE

          本文链接:https://www.haomeiwen.com/subject/vqbnhxtx.html