推荐学习书目
› 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 · Apr 18, 2016 · 9750 views
    This topic created in 3860 days ago, the information mentioned may be changed or developed.

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

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

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

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

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

    u'sadfsa'

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

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

    估计还是你页面上收集到的数据没有做校验转码而产生的错误
    vJianZhen
    vJianZhen
    OP
    Apr 18, 2016
    31
    @Tink 因为对 Linux 平台不熟悉,出了问题更懵逼
    vJianZhen
    vJianZhen
    OP
    Apr 18, 2016
    32
    @neoblackcap 首先谢谢你。不知道你实现时版本一样吗?我现在很怀疑是版本的 bug 或者是隐藏很深的问题。从页面上只收集了一个『 username 』,提交的还是『 Kobe 』……通过命令行能打印出来。
    hahastudio
    hahastudio
    Apr 18, 2016
    33
    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
    neoblackcap
    Apr 18, 2016
    34
    @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
    vJianZhen
    OP
    Apr 18, 2016
    35
    @hahastudio 列也有字符集确实是个新观念。问题是,在视图函数上通过 create_all()来创建表的时候问题就出现了,根本不涉及插入。
    vJianZhen
    vJianZhen
    OP
    Apr 18, 2016
    36
    @neoblackcap 版本几乎都一样。我就更懵逼了……
    pixstone
    pixstone
    Apr 18, 2016
    37
    @loading 已经不建议 用 u “中文” 这种形式了,推荐: from __future__ import unicode_literals ,配合 # coding=utf-8
    。

    然后 还有一个 歪招:

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

    @vJianZhen 找到了,额, sqlalchemy 问题,在 win 下需要调整下“更改系统区域设置”属性(具体位置百度)为英语(美国)搞定。
    vJianZhen
    vJianZhen
    OP
    Apr 18, 2016
    55
    @florije 开始用着 PyCharm 的,用着用着觉得很多事它帮我做了,这样对理解没帮助。现在正在试你的方法了……
    florije
    florije
    Apr 18, 2016❤️1
    56
    @vJianZhen 额,我的意思是你代码有问题, User 类里面的 username 属性你拼写错成 usrname 了,然后一般的我推荐用 filter 方法,直接用类.属性,不容易出错,至于 pycharm 看你怎么用了,格式化下了,看下代码有没问题了之类的完全可以用嘛。
    vJianZhen
    vJianZhen
    OP
    Apr 18, 2016
    57
    @florije 你……你你你,我……我我……问题被你解决了!把拼写写对了,也更改了系统设置,运行 OK 了。太谢谢。
    jwk345
    jwk345
    Apr 18, 2016
    58
    cmd 的问题?如果你 Windows 是中文的,默认终端就是 GBK
    vJianZhen
    vJianZhen
    OP
    Apr 18, 2016
    59
    @florije 现在是这样,把拼写写好,能运行起来,虽然有警告;如果再把“更改系统区域设置”为英语(美国),既不出警告,也能正常运行。问题已经解决了。那请问你知道为什么吗?就是原理上的东西。
    hahastudio
    hahastudio
    Apr 18, 2016 via Android
    60
    @vJianZhen cmd 的编码从 CP936 变成 CP1252 了?
    glasslion
    glasslion
    Apr 19, 2016
    61
    @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
    vJianZhen
    OP
    Apr 19, 2016 via iPad
    62
    @hahastudio 没有。这个警告可以通过更改系统区域设置来消除。另外,我把 username 拼写成 usrname 了,否则有警告也可以运行出来的。我很自责。
    ibigbug
    ibigbug
    Apr 19, 2016
    63
    @pixstone 的 in text 这个是什么魔法
    ipconfiger
    ipconfiger
    Apr 19, 2016
    64
    自从弃了瘟到死就很少遇到编码问题了
    picasso250
    picasso250
    Apr 19, 2016
    65
    每次别人遇到编码问题,我都建议他换 PHP 。
    但是没有一次别人认为我是真诚的。
    jugelizi
    jugelizi
    Apr 19, 2016
    66
    哈哈
    曾经在 win 下坑死
    一段小代码 py2.7 运行没有任何报错就是没返回 扔到 linux 下很快结果出来了
    zjj2008se
    zjj2008se
    Apr 19, 2016 via Android
    67
    win 下面的编码一泡污,就算 py3 还是会 gbk 报错,除了改区域没别的办法。
    pynix
    pynix
    Apr 19, 2016 via Android
    68
    主要问题就是在 Windows 下折腾。。
    XiMing
    XiMing
    Apr 19, 2016
    69
    收藏一波,感觉我也会遇到。
    Crixs
    Crixs
    Apr 19, 2016
    70
    看到问题解决了还是很开心的,很多人根本不看问题和用的版本,乱说一通,给 @florije 赞一个
    zonghua
    zonghua
    Apr 20, 2016 via iPhone
    71
    困扰了我许久,文件下载的时候怎么用中文命名?试过多钟方法均无效
    TGlivecoding
    TGlivecoding
    Apr 23, 2016
    72
    如果是 3 的话我用 3 实现过一遍这本书代码: https://github.com/taogeT/flask_web_development_python3 ,不知道对你有没有帮助?
    florije
    florije
    May 10, 2016❤️1
    73
    @vJianZhen 其实问题在 mysql 上面,如果没猜错,你用的 mysql 是 5.7.*的,貌似里面验证什么地方编码的东西了。换上 5.6.*就没有这个提示了,当然上面系统编码修改那个算是临时的方案吧。
    vJianZhen
    vJianZhen
    OP
    May 10, 2016
    74
    @florije 确实是 5.7
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   4616 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 109ms · UTC 06:25 · PVG 14:25 · LAX 22:25 · JFK 01:25
    ♥ Do have faith in what you're doing.