一、問題
這兩天在學(xué)習(xí)使用flask + SQLAlchemy 定制一個(gè)web查詢頁(yè)面的demo ,在測(cè)試時(shí),發(fā)現(xiàn)查詢到的結(jié)果顯示亂碼 。這里將解決方法記錄下。
二、解決思路
1、flask 程序上定位
flask的文檔中提到可以通過(guò)設(shè)置SQLALCHEMY_NATIVE_UNICODE來(lái)禁止使用SQLAlchemy默認(rèn)的Unicode編碼。有可能是SQLAlchemy默認(rèn)的Unicode編碼不是UTF-8,抱著這樣的想法,在程序中指定了“SQLALCHEMY_NATIVE_UNICODE=False”,執(zhí)行程序,報(bào)錯(cuò)。
flask中還提到“use_native_unicode”為目標(biāo)編碼來(lái)指定編碼方式,嘗試將“db = SQLAlchemy(app)”改為“db = SQLAlchemy(app, use_native_unicode="utf8")”。這回雖然沒報(bào)錯(cuò),但還是亂碼。
2、mysql 上定位
突然想到有可能是建表的時(shí)候,沒有指定字符集,使用的是數(shù)據(jù)庫(kù)默認(rèn)的字符集的導(dǎo)致的。繼續(xù)找了一段時(shí)間的如何指定建表時(shí)使用字符集的方法,未果。
數(shù)據(jù)庫(kù)該不會(huì)使用的不是UTF-8吧?抱著這個(gè)想法,進(jìn)入數(shù)據(jù)庫(kù),輸入“status”,在輸出的信息上顯示默認(rèn)是latin-1。搞了半天,原來(lái)問題在這。
mysql> status -------------- mysql Ver 14.14 Distrib 5.1.73, for redhat-linux-gnu (x86_64) using readline 5.1 Connection id: 9 Current database: web12306 Current user: root@localhost SSL: Not in use Current pager: stdout Using outfile: '' Using delimiter: ; Server version: 5.1.73 Source distribution Protocol version: 10 Connection: Localhost via UNIX socket Server characterset: utf8 Db characterset: utf8 Client characterset: latin1 Conn. characterset: latin1 UNIX socket: /var/lib/mysql/mysql.sock
3、解決問題
即然找到了,問題就在mysql 的my.cnf 上增加相關(guān)配置,并重啟mysql 服務(wù):
# 進(jìn)入mysql的配置文件目錄 cd /etc/mysql/ # 編輯my.cnf配置文件 vim my.cnf # 在文件中的[mysqld]下面增加一行內(nèi)容 character_set_server = utf8 # 在[client]和[mysql]下面分別增加一行內(nèi)容 default-character-set = utf8 # 保存。然后重啟MySQL的服務(wù),設(shè)置就生效了 service mysqld restart
注:需要注意的是,之前已經(jīng)存在的數(shù)據(jù),在上面修改過(guò)后,通過(guò)mysql select查詢時(shí)會(huì)是亂碼,需要重新導(dǎo)入。
PS
:Python下SQLAlchemy真的是super好用,不太了解的童鞋可以嘗試一下下面這個(gè)MySQL的例子:
#!/usr/bin/env python # -*- coding: UTF-8 -*- from sqlalchemy.orm import mapper, sessionmaker __author__ = 'tan9le' from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData from sqlalchemy.sql.expression import Cast from sqlalchemy.ext.compiler import compiles from sqlalchemy.dialects.mysql import \ BIGINT, BINARY, BIT, BLOB, BOOLEAN, CHAR, DATE, \ DATETIME, DECIMAL, DECIMAL, DOUBLE, ENUM, FLOAT, INTEGER, \ LONGBLOB, LONGTEXT, MEDIUMBLOB, MEDIUMINT, MEDIUMTEXT, NCHAR, \ NUMERIC, NVARCHAR, REAL, SET, SMALLINT, TEXT, TIME, TIMESTAMP, \ TINYBLOB, TINYINT, TINYTEXT, VARBINARY, VARCHAR, YEAR #表的屬性描述對(duì)象 metadata = MetaData() userTable = Table( "wzp_user",metadata, Column('user_id', Integer, primary_key=True), Column('user_name', VARCHAR(50), unique=True, nullable=False), Column('password', VARCHAR(40), nullable=True) ) #創(chuàng)建數(shù)據(jù)庫(kù)連接,MySQLdb連接方式 mysql_db = create_engine('mysql://用戶名:密碼@ip:port/dbname') #創(chuàng)建數(shù)據(jù)庫(kù)連接,使用 mysql-connector-python連接方式 #mysql_db = create_engine("mysql+mysqlconnector://用戶名:密碼@ip:port/dbname") #生成表 metadata.create_all(mysql_db) #創(chuàng)建一個(gè)映射類 class User(object): pass #把表映射到類 mapper(User, userTable) #創(chuàng)建了一個(gè)自定義了的 Session類 Session = sessionmaker() #將創(chuàng)建的數(shù)據(jù)庫(kù)連接關(guān)聯(lián)到這個(gè)session Session.configure(bind=mysql_db) session = Session() def main(): u = User() #給映射類添加以下必要的屬性,因?yàn)樯厦鎰?chuàng)建表指定這個(gè)字段不能為空,且唯一 u.user_name='tan9le測(cè)試' #按照上面創(chuàng)建表的相關(guān)代碼,這個(gè)字段允許為空 u.password='123456' #在session中添加內(nèi)容 session.add(u) #保存數(shù)據(jù) session.flush() #數(shù)據(jù)庫(kù)事務(wù)的提交,sisson自動(dòng)過(guò)期而不需要關(guān)閉 session.commit() #query() 簡(jiǎn)單的理解就是select() 的支持 ORM 的替代方法,可以接受任意組合的 class/column 表達(dá)式 query = session.query(User) #列出所有user print list(query) #根據(jù)主鍵顯示 print query.get(1) #類似于SQL的where,打印其中的第一個(gè) print query.filter_by(user_name='tan9le測(cè)試').first() u = query.filter_by(user_name='tan9le測(cè)試').first() #修改其密碼字段 u.password = '654321' #提交事務(wù) session.commit() #打印會(huì)出現(xiàn)新密碼 print query.get(1).password #根據(jù)id字段排序,打印其中的用戶名和密碼 for instance in session.query(User).order_by(User.user_id): print instance.user_name, instance.password #釋放資源 session.close() if __name__ == '__main__': main()
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
