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 · 8233 次点击
    这是一个创建于 3175 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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  
       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   ·   实用小工具   ·   998 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 23:01 · PVG 07:01 · LAX 15:01 · JFK 18:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.