被编码问题搞炸了! - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
vJianZhen
V2EX    Python

被编码问题搞炸了!

  •  
  •   vJianZhen 2016-04-18 15:57:50 +08:00 8714 次点击
    这是一个创建于 3463 天前的主题,其中的信息可能已经有所发展或是发生改变。

    http://i3.piimg.com/d031ecea9295bc8c.png

    做毕业设计,目前跟着《 Flask Web 开发》敲代码。 到了数据库这段,进行不下去了,因为编码问题。 文件的编码、连接编码、数据库编码、校验编码……不明所以,一团混乱。 图上的虽然是个警告,但是不消灭没法下一步。 网上找了一圈,还是没有方案能解决。 有大神知道怎么解决吗?还请不吝赐教~万分感谢!

    74 条回复    2016-05-10 14:47:48 +08:00
    florije
        1
    florije  
       2016-04-18 16:09:02 +08:00   1
    扔到 git 上或者啥地方,帮你看下。
    neoblackcap
        2
    neoblackcap  
       2016-04-18 16:19:00 +08:00
    大致推测就是你建的表的默认值跟该字段的类型不符

    建议你将数据库类型,你的 Model 都放出来。同时提问的时候请参考, http://zhuanlan.zhihu.com/p/20752519
    gssdromen
        3
    gssdromen  
       2016-04-18 16:20:04 +08:00
    把出问题的地方代码贴一下看看呗
    viease
        4
    viease  
       2016-04-18 16:36:43 +08:00
    show 你的 git
    vJianZhen
        5
    vJianZhen  
    OP
       2016-04-18 16:44:36 +08:00
    各位,在百度云 http://pan.baidu.com/s/1o8Ijnce 看吧……
    尝试了很久,还是没能 push 上 github 。
    出错的地方大概在 hello.py 的第 69 行,查询数据库那行。
    vJianZhen
        6
    vJianZhen  
    OP
       2016-04-18 16:50:25 +08:00
    代码在此处
    https://gist.github.com/mafanshu/4d557b6ff32049fe59f202d9c8231770
    这个功能刚才才知道……@neoblackcap
    mornlight
        7
    mornlight  
       2016-04-18 16:56:15 +08:00
    user = User(username=form.name.data)

    你 debug 一下 form.name.data 是个什么东西,啥类型
    kaneg
        8
    kaneg  
       2016-04-18 17:07:50 +08:00
    你的 python 文件中有中文,应该在文件第一行加 encoding 声明:
    #encoding=utf-8
    haozhang
        9
    haozhang  
       2016-04-18 17:11:33 +08:00 via iPhone
    三码合一: python 代码文件编码, mysql 连接时的编码, mysql 数据库存储的编码
    vJianZhen
        10
    vJianZhen  
    OP
       2016-04-18 17:19:21 +08:00
    @mornlight 是从表单里获得的文本框里的数据,字符串类型
    @kaneg 声明后没变化
    vJianZhen
        11
    vJianZhen  
    OP
       2016-04-18 17:25:00 +08:00
    @haozhang Python 代码文件编码 utf-8 , MySQL 中 character_set_connection 值为 utf-8 , character_set_database 值为 utf8mb4 (原本是 utf8 ,后来根据网上的说法改成这样,都没用)
    vJianZhen
        12
    vJianZhen  
    OP
       2016-04-18 17:25:41 +08:00
    另外,在浏览器上报的是 500 错误。书本对应的项目地址: https://github.com/miguelgrinberg/flasky
    Vamwere
        13
    Vamwere  
       2016-04-18 17:27:50 +08:00
    这个时候是不是应该说一句请用 python3 ?
    loading
        14
    loading  
       2016-04-18 17:29:58 +08:00
    如果使用 py2 ,请在所有字符串前面加上 u ,也就是:

    u'sadfsa'

    多用 decode,encode
    vJianZhen
        15
    vJianZhen  
    OP
       2016-04-18 17:30:18 +08:00
    @Vamwere 用的就是 Python3.5.32 ,但我觉得也有版本不匹配的因素才导致了问题。=
    vJianZhen
        16
    vJianZhen  
    OP
       2016-04-18 17:32:18 +08:00
    Python 的版本是 3.5.1 。
    hahastudio
        17
    hahastudio  
       2016-04-18 17:35:19 +08:00
    >>> print "\xD6\xD0\xB9\xFA\xB1\xEA".decode("gbk")
    中国标
    你有地方存的数据是 GBK 编码的

    Python 别老跟 Windows 一起用= =
    vJianZhen
        18
    vJianZhen  
    OP
       2016-04-18 17:48:40 +08:00
    @hahastudio 所有能想到的地方都是 utf8 编码的,实在不知道哪里有数据是 gbk 编码。==。用 Windows 是因为习惯,慢慢会转 Linux 或 MAC
    florije
        19
    florije  
       2016-04-18 17:52:12 +08:00
    好吧,本地全 utf-8 环境 db.create_all()是没有任何问题的。
    form.name.data 这个的编码是 GBK ,搜下 mysql 相关的就能找到这个错误。
    vJianZhen
        20
    vJianZhen  
    OP
       2016-04-18 17:52:38 +08:00
    而且没有『中国标』这三个字的数据,我不知道它从哪里冒出来的==。难道是 PyMySQL 的行为么?
    dphdjy
        21
    dphdjy  
       2016-04-18 17:56:06 +08:00 via Android   2
    国标是习惯简称。。。
    GBK 国标扩
    florije
        22
    florije  
       2016-04-18 17:57:57 +08:00
    如果没猜错肯定有一个地方用到了%z 的,类似 time.strftime('%z'),也就是会输出中国标准时间。
    vJianZhen
        23
    vJianZhen  
    OP
       2016-04-18 17:58:32 +08:00
    form.name.data 这个字段是从网页上请求上来的,我查看了页面的编码也是 utf8 的。"\xD6\xD0\xB9\xFA\xB1\xEA"根据 gbk 编码解码后是『中国标』三个字,但是这三个字我们提交过,况且我提交的都是英文。页面的效果如图: http://i2.piimg.com/9c238b4453491952.png
    vJianZhen
        24
    vJianZhen  
    OP
       2016-04-18 18:03:00 +08:00
    @florije 目前在数据库方面没有涉及时间,除非是 PyMySQL/MySQL 等自己的行为。目前数据库上面只有两个表,列也是非常简单的字段。涉及到时间的在前端用了 Flask-Moment ,但是诚如效果图所示,是用英文显示的。
    pixstone
        25
    pixstone  
       2016-04-18 18:04:42 +08:00
    http://nedbatchelder.com/text/unipain.html
    看篇,很好的解释了编码问题。
    vJianZhen
        26
    vJianZhen  
    OP
       2016-04-18 18:08:36 +08:00
    @pixstone 但是……英文的,篇幅有点长,怕来不及消化。现在只想快点把问题解决掉。
    est
        27
    est  
       2016-04-18 18:09:45 +08:00
    py2, windows, gbk ,三码合一就直接把新手炸毛了
    vJianZhen
        28
    vJianZhen  
    OP
       2016-04-18 18:10:31 +08:00
    @est 对,我实在要哭了!
    Tink
        29
    Tink  
    PRO
       2016-04-18 18:11:04 +08:00 via iPhone
    为啥用 windows 呢
    neoblackcap
        30
    neoblackcap  
       2016-04-18 18:13:42 +08:00
    已经在 linux 下面实现过一次,像你截图一样调用 create_all 方法并不会报错。

    估计还是你页面上收集到的数据没有做校验转码而产生的错误
    vJianZhen
        31
    vJianZhen  
    OP
       2016-04-18 18:16:18 +08:00
    @Tink 因为对 Linux 平台不熟悉,出了问题更懵逼
    vJianZhen
        32
    vJianZhen  
    OP
       2016-04-18 18:19:14 +08:00
    @neoblackcap 首先谢谢你。不知道你实现时版本一样吗?我现在很怀疑是版本的 bug 或者是隐藏很深的问题。从页面上只收集了一个『 username 』,提交的还是『 Kobe 』……通过命令行能打印出来。
    hahastudio
        33
    hahastudio  
       2016-04-18 18:27:22 +08:00
    http://blog.wifibao.im/index.php/archives/158/
    是不是新手都有这问题

    https://stackoverflow.com/questions/2108824/mysql-incorrect-string-value-error-when-save-unicode-string-in-django
    columns can have their own character sets, independent of the tables and the database.
    neoblackcap
        34
    neoblackcap  
       2016-04-18 18:33:39 +08:00
    @vJianZhen
    python 是 3.5.0, 各类包如下
    dominate (2.2.0)
    Flask (0.10.1)
    Flask-Bootstrap (3.3.5.7)
    Flask-Moment (0.5.1)
    Flask-Script (2.0.5)
    Flask-SQLAlchemy (2.1)
    Flask-WTF (0.12)
    itsdangerous (0.24)
    Jinja2 (2.8)
    MarkupSafe (0.23)
    pip (7.1.2)
    PyMySQL (0.7.2)
    setuptools (18.2)
    SQLAlchemy (1.0.12)
    visitor (0.1.2)
    Werkzeug (0.11.8)
    WTForms (2.1)

    至于 MySQL 也是使用 5.7 了
    vJianZhen
        35
    vJianZhen  
    OP
       2016-04-18 18:45:45 +08:00
    @hahastudio 列也有字符集确实是个新观念。问题是,在视图函数上通过 create_all()来创建表的时候问题就出现了,根本不涉及插入。
    vJianZhen
        36
    vJianZhen  
    OP
       2016-04-18 18:47:47 +08:00
    @neoblackcap 版本几乎都一样。我就更懵逼了……
    pixstone
        37
    pixstone  
       2016-04-18 19:05:01 +08:00
    @loading 已经不建议 用 u “中文” 这种形式了,推荐: from __future__ import unicode_literals ,配合 # coding=utf-8


    然后 还有一个 歪招:

    if "的" in text: 这个(之前 V2 的帖子看到)
    guyskk
        38
    guyskk  
       2016-04-18 19:15:46 +08:00
    如果还没解决的话, pdb 调试
    http://python.jobbole.com/81184/
    feng32
        39
    feng32  
       2016-04-18 19:25:57 +08:00
    用全英文就行了, UI 看起来更专业,而且别人还不知道你是为了避免处理编码问题
    windfarer
        40
    windfarer  
       2016-04-18 19:40:53 +08:00 via Android
    Python3 一劳永逸
    loading
        41
    loading  
       2016-04-18 19:51:17 +08:00 via Android
    @pixstone 用过,有坑!
    loading
        42
    loading  
       2016-04-18 19:52:18 +08:00 via Android
    个人建议,楼主直接上 py3 ,目测楼主还没写几行!
    zhuangzhuang1988
        43
    zhuangzhuang1988  
       2016-04-18 19:55:08 +08:00
    pycharm 一行行调试。。
    imkh
        44
    imkh  
       2016-04-18 19:58:28 +08:00 via iPhone   1
    笑了,一群说用 Python 3 的都眼瞎了吧?也不看楼主的补充说明
    cxbig
        45
    cxbig  
       2016-04-18 19:59:15 +08:00
    换 Linux 或 Mac OS 来开发吧
    loading
        46
    loading  
       2016-04-18 20:13:15 +08:00 via Android
    看来 py3 也是醉人…
    vJianZhen
        47
    vJianZhen  
    OP
       2016-04-18 21:40:34 +08:00
    @cxbig 时间紧,别的平台也不熟悉
    vJianZhen
        48
    vJianZhen  
    OP
       2016-04-18 21:41:30 +08:00
    @feng32 全是中文,也出问题
    WangYanjie
        49
    WangYanjie  
       2016-04-18 21:42:18 +08:00
    @kaneg 中文应该是作者后来加的
    florije
        50
    florije  
       2016-04-18 21:51:38 +08:00
    user = User.query.filter_by(usrname=form.name.data).first()
    唉,楼主能跟我说下 usrname 是什么吗?
    florije
        51
    florije  
       2016-04-18 21:52:25 +08:00
    虽然很喜欢 LZ 的钻研精神,但是还是建议刚刚接触新知识还是用点只能的 IDE 比较靠谱。
    florije
        52
    florije  
       2016-04-18 21:58:36 +08:00   1
    真心没必要开系统炮,然后发现家里电脑也有类似 lz 的 warning ,但是公司的没有,稍后我看看是哪里提示的,貌似是 sqlalchemy 抛出的。
    Kilerd
        53
    Kilerd  
       2016-04-18 22:02:20 +08:00
    只能说玩不来 编码,就乖乖的去 用 Python3 吧。
    florije
        54
    florije  
       2016-04-18 22:07:55 +08:00   1
    @Kilerd 能别开编码炮了么……上面已经找到问题了。

    @vJianZhen 找到了,额, sqlalchemy 问题,在 win 下需要调整下“更改系统区域设置”属性(具体位置百度)为英语(美国)搞定。
    vJianZhen
        55
    vJianZhen  
    OP
       2016-04-18 22:11:44 +08:00
    @florije 开始用着 PyCharm 的,用着用着觉得很多事它帮我做了,这样对理解没帮助。现在正在试你的方法了……
    florije
        56
    florije  
       2016-04-18 22:15:00 +08:00   1
    @vJianZhen 额,我的意思是你代码有问题, User 类里面的 username 属性你拼写错成 usrname 了,然后一般的我推荐用 filter 方法,直接用类.属性,不容易出错,至于 pycharm 看你怎么用了,格式化下了,看下代码有没问题了之类的完全可以用嘛。
    vJianZhen
        57
    vJianZhen  
    OP
       2016-04-18 22:23:49 +08:00
    @florije 你……你你你,我……我我……问题被你解决了!把拼写写对了,也更改了系统设置,运行 OK 了。太谢谢。
    jamesxu
        58
    jamesxu  
       2016-04-18 22:28:47 +08:00
    cmd 的问题?如果你 Windows 是中文的,默认终端就是 GBK
    vJianZhen
        59
    vJianZhen  
    OP
       2016-04-18 22:35:38 +08:00
    @florije 现在是这样,把拼写写好,能运行起来,虽然有警告;如果再把“更改系统区域设置”为英语(美国),既不出警告,也能正常运行。问题已经解决了。那请问你知道为什么吗?就是原理上的东西。
    hahastudio
        60
    hahastudio  
       2016-04-18 23:35:52 +08:00 via Android
    @vJianZhen cmd 的编码从 CP936 变成 CP1252 了?
    glasslion
        61
    glasslion  
       2016-04-19 00:02:10 +08:00
    @vJianZhen 分别在 Linux/Mac 和 Windows 下运行下面的代码, Linux 下这几个 encoding 全部是 utf8 而 windows 则是千奇百怪



    ```
    import sys, locale

    expressiOns= """
    locale.getpreferredencoding()
    type(my_file)
    my_file.encoding
    sys.stdout.isatty()
    sys.stdout.encoding
    sys.stdin.isatty()
    sys.stdin.encoding
    sys.stderr.isatty()
    sys.stderr.encoding
    sys.getdefaultencoding()
    sys.getfilesystemencoding()
    """

    my_file = open('dummy', 'w')

    for expression in expressions.split():
    value = eval(expression)
    print(expression.rjust(30), '->', repr(value))

    ```

    Python 和 encoding 1 相关的配置主要有下面几个:
    1. ` locale.getpreferredencoding()` 这个用的是最广的。 这是 Python 在 open 文件时默认使用的 encoding
    2. `sys.getdefaultencoding() ` 是 Python 进行 str/unicode(byte/str) 转换时默认使用的 encoding
    3. `sys.getfilesystemencoding()` 是用来 encoding 文件**名**的, 例如 open(b'balabala')
    4. 标准输入输出(print)的 encoding:
    4.1 若设置了 `PYTHONIOENCODING` 环境变量, 则以次变量为准
    4.2 标准输入输出是打到终端的话, 看终端的 locale 配置, 在 windows cmd 的代码页
    4.3 标准输入输出被重定向到文件的话, 则参照 1 , 用的是 ` locale.getpreferredencoding()`

    @hahastudio
    @hahastudio
    vJianZhen
        62
    vJianZhen  
    OP
       2016-04-19 00:13:03 +08:00 via iPad
    @hahastudio 没有。这个警告可以通过更改系统区域设置来消除。另外,我把 username 拼写成 usrname 了,否则有警告也可以运行出来的。我很自责。
    ibigbug
        63
    ibigbug  
       2016-04-19 02:48:05 +08:00
    @pixstone 的 in text 这个是什么魔法
    ipconfiger
        64
    ipconfiger  
       2016-04-19 08:53:51 +08:00
    自从弃了瘟到死就很少遇到编码问题了
    picasso250
        65
    picasso250  
       2016-04-19 10:00:17 +08:00
    每次别人遇到编码问题,我都建议他换 PHP 。
    但是没有一次别人认为我是真诚的。
    jugelizi
        66
    jugelizi  
       2016-04-19 10:39:30 +08:00
    哈哈
    曾经在 win 下坑死
    一段小代码 py2.7 运行没有任何报错就是没返回 扔到 linux 下很快结果出来了
    zjj2008se
        67
    zjj2008se  
       2016-04-19 11:16:36 +08:00 via Android
    win 下面的编码一泡污,就算 py3 还是会 gbk 报错,除了改区域没别的办法。
    pynix
        68
    pynix  
       2016-04-19 12:36:17 +08:00 via Android
    主要问题就是在 Windows 下折腾。。
    XiMing
        69
    XiMing  
       2016-04-19 13:14:55 +08:00
    收藏一波,感觉我也会遇到。
    RockShake
        70
    RockShake  
       2016-04-19 13:31:37 +08:00
    看到问题解决了还是很开心的,很多人根本不看问题和用的版本,乱说一通,给 @florije 赞一个
    zonghua
        71
    zonghua  
       2016-04-20 01:33:22 +08:00 via iPhone
    困扰了我许久,文件下载的时候怎么用中文命名?试过多钟方法均无效
    TGlivecoding
        72
    TGlivecoding  
       2016-04-23 23:06:28 +08:00
    如果是 3 的话我用 3 实现过一遍这本书代码: https://github.com/taogeT/flask_web_development_python3 ,不知道对你有没有帮助?
    florije
        73
    florije  
       2016-05-10 10:47:32 +08:00   1
    @vJianZhen 其实问题在 mysql 上面,如果没猜错,你用的 mysql 是 5.7.*的,貌似里面验证什么地方编码的东西了。换上 5.6.*就没有这个提示了,当然上面系统编码修改那个算是临时的方案吧。
    vJianZhen
        74
    vJianZhen  
    OP
       2016-05-10 14:47:48 +08:00
    @florije 确实是 5.7
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3273 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 00:05 PVG 08:05 LAX 17:05 JFK 20:05
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86