推荐学习书目
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 · Aug 16, 2017 · 4780 views
    This topic created in 3206 days ago, the information mentioned may be changed or developed.

    我初学 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 replies    2017-08-16 15:19:45 +08:00
    daviswei
        1
    daviswei  
    OP
       Aug 16, 2017
    自己顶起来,是不是该考虑每个 class 自己写个查询方法了。。。可是这样的话,我还想用 filter 怎么办
    daviswei
        2
    daviswei  
    OP
       Aug 16, 2017
    想通了,进出都不转码,库里面记录是乱码就乱码吧
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5360 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 01:30 · PVG 09:30 · LAX 18:30 · JFK 21:30
    ♥ Do have faith in what you're doing.