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
daviswei
V2EX  ›  Python

请教关于 flask-sqlalchemy 查询 oracle 库时, query.all()查询中编码的问题

  •  
  •   daviswei · 2017-08-16 00:19:17 +08:00 · 4078 次点击
    这是一个创建于 2686 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我初学 python,打算照着网上的例程,用 flask 搭一个笔记网站练手,因为想着尽量贴近公司现有的基础资源,所以数据库没有照例程的用 mongoDB,而是直接连公司的 oracle 数据库,悲催的是这个库编码已经是 ZHS16GBK,不可能更改,而且也会是以后绕不过的一个坑,所以还是得将这个骨头啃下来。   现在的困难是,我能成功建表、写入数据,在构造 class 的时候,我增加了 toGBK()方法,将几个字段都转码,这样写进去的中文也是正常格式了。我还写了个 toUTF8()方法,准备照样子将查询出来的结果转为 UTF-8,可惜在 Note.query.all()这一步查询时就报错了,错误信息是: UnicodeDecodeError: 'utf8' codec can't decode byte 0xbf in position 0: invalid start byte

    我直接自己写 sql 去查,都能成功转码,不懂为啥用了 query.all()就出错了。下面是我测试环境和两个相关文件代码,希望大家帮忙。

    先列一下我这边的版本:

    服务器:64 位 centos 7.3.1611
    系统编码环境: 
        LANG=en_US.UTF-8
        NLS_LANG='SIMPLIFIED CHINESE_CHINA.ZHS16GBK'
    
    Python 2.7.5
    
    cx-Oracle==5.3
    decorator==3.4.0
    ez-setup==0.9
    Flask==0.12.2
    Flask-Script==2.0.5
    Flask-SQLAlchemy==2.2
    SQLAlchemy==1.1.13
    
    oracle 数据库和客户端的版本都是 11.2.0.4
    

    app/models.py 文件

    from app import db
    import datetime
    
    class Note(db.Model):
    	__tablename__ = 'WKNT_NOTES'
    	id_seq = db.Sequence('WKNT_NOTES_ID_SEQ')
    
    	id       = db.Column(db.Integer, id_seq, primary_key=True)
    	created  = db.Column(db.DateTime, default=datetime.datetime.now())
    	category = db.Column(db.String(60))
    	opt      = db.Column(db.String(60))
    	content  = db.Column(db.String(2000))
    	name     = db.Column(db.String(60))
    
    	def __init__(self, category, opt, content, name):
    		self.category = category
    		self.opt      = opt
    		self.content  = content
    		self.name     = name
    
    	def __repr__(self):
    		return '<ID %r>' % self.id
    
    	def toGBK(self):
    		self.category = self.category.decode("utf-8").encode("GBK")
    		self.opt      = self.opt.decode("utf-8").encode("GBK")
    		self.content  = self.content.decode("utf-8").encode("GBK")
    		self.name     = self.name.decode("utf-8").encode("GBK")
    		return self
    
    	def toUTF8(self):
    		self.category = self.category.decode("GBK").encode("utf-8")
    		self.opt      = self.opt.decode("GBK").encode("utf-8")
    		self.content  = self.content.decode("GBK").encode("utf-8")
    		self.name     = self.name.decode("GBK").encode("utf-8")
    		return self
    

    manage.py 文件

    # -*- coding: utf-8 -*-
    
    from flask_script import Manager, Server
    from app import *
    
    manager = Manager(app)
    
    manager.add_command("runserver", Server(host='0.0.0.0',port=80, use_debugger=True))
    
    @manager.command
    def save_note():
    	note = models.Note(
    				content='开张大吉',
    				name='daviswei',
    				opt='create',
    				category='网络')
    	note.toGBK()
    	db.create_all()
    	db.session.add(note)
    	db.session.commit()
    
    @manager.command
    def read_note():
    	notes = models.Note.query.all()
    	for n in notes:
    		n.toUTF8()
    		print(n)
    
    @manager.command
    def read_direct():
    	sql = 'select * from wknt_notes'
    	for notes in db.engine.execute(sql):
    		print notes.content.decode("GBK").encode("utf-8")
    
    if __name__ == '__main__':
    	manager.run()
    
    2 条回复    2017-08-16 15:19:45 +08:00
    daviswei
        1
    daviswei  
    OP
       2017-08-16 14:24:55 +08:00
    自己顶起来,是不是该考虑每个 class 自己写个查询方法了。。。可是这样的话,我还想用 filter 怎么办
    daviswei
        2
    daviswei  
    OP
       2017-08-16 15:19:45 +08:00
    想通了,进出都不转码,库里面记录是乱码就乱码吧
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1057 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 18:13 · PVG 02:13 · LAX 10:13 · JFK 13:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.