Python的Flask框架中SQLAlchemy使用時的亂碼問題解決
一、問題
這兩天在學習使用flask + SQLAlchemy 定制一個web查詢頁面的demo ,在測試時,發(fā)現(xiàn)查詢到的結(jié)果顯示亂碼 。這里將解決方法記錄下。
二、解決思路
1、flask 程序上定位
flask的文檔中提到可以通過設(shè)置SQLALCHEMY_NATIVE_UNICODE來禁止使用SQLAlchemy默認的Unicode編碼。有可能是SQLAlchemy默認的Unicode編碼不是UTF-8,抱著這樣的想法,在程序中指定了“SQLALCHEMY_NATIVE_UNICODE=False”,執(zhí)行程序,報錯。
flask中還提到“use_native_unicode”為目標編碼來指定編碼方式,嘗試將“db = SQLAlchemy(app)”改為“db = SQLAlchemy(app, use_native_unicode="utf8")”。這回雖然沒報錯,但還是亂碼。
2、mysql 上定位
突然想到有可能是建表的時候,沒有指定字符集,使用的是數(shù)據(jù)庫默認的字符集的導致的。繼續(xù)找了一段時間的如何指定建表時使用字符集的方法,未果。
數(shù)據(jù)庫該不會使用的不是UTF-8吧?抱著這個想法,進入數(shù)據(jù)庫,輸入“status”,在輸出的信息上顯示默認是latin-1。搞了半天,原來問題在這。
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 服務:
# 進入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的服務,設(shè)置就生效了 service mysqld restart
注:需要注意的是,之前已經(jīng)存在的數(shù)據(jù),在上面修改過后,通過mysql select查詢時會是亂碼,需要重新導入。
PS:Python下SQLAlchemy真的是super好用,不太了解的童鞋可以嘗試一下下面這個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
#表的屬性描述對象
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ù)庫連接,MySQLdb連接方式
mysql_db = create_engine('mysql://用戶名:密碼@ip:port/dbname')
#創(chuàng)建數(shù)據(jù)庫連接,使用 mysql-connector-python連接方式
#mysql_db = create_engine("mysql+mysqlconnector://用戶名:密碼@ip:port/dbname")
#生成表
metadata.create_all(mysql_db)
#創(chuàng)建一個映射類
class User(object):
pass
#把表映射到類
mapper(User, userTable)
#創(chuàng)建了一個自定義了的 Session類
Session = sessionmaker()
#將創(chuàng)建的數(shù)據(jù)庫連接關(guān)聯(lián)到這個session
Session.configure(bind=mysql_db)
session = Session()
def main():
u = User()
#給映射類添加以下必要的屬性,因為上面創(chuàng)建表指定這個字段不能為空,且唯一
u.user_name='tan9le測試'
#按照上面創(chuàng)建表的相關(guān)代碼,這個字段允許為空
u.password='123456'
#在session中添加內(nèi)容
session.add(u)
#保存數(shù)據(jù)
session.flush()
#數(shù)據(jù)庫事務的提交,sisson自動過期而不需要關(guān)閉
session.commit()
#query() 簡單的理解就是select() 的支持 ORM 的替代方法,可以接受任意組合的 class/column 表達式
query = session.query(User)
#列出所有user
print list(query)
#根據(jù)主鍵顯示
print query.get(1)
#類似于SQL的where,打印其中的第一個
print query.filter_by(user_name='tan9le測試').first()
u = query.filter_by(user_name='tan9le測試').first()
#修改其密碼字段
u.password = '654321'
#提交事務
session.commit()
#打印會出現(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()
相關(guān)文章
python多線程+代理池爬取天天基金網(wǎng)、股票數(shù)據(jù)過程解析
這篇文章主要介紹了python多線程+代理池爬取天天基金網(wǎng)、股票數(shù)據(jù)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-08-08
Pytorch+PyG實現(xiàn)EdgeCNN過程示例詳解
這篇文章主要為大家介紹了Pytorch+PyG實現(xiàn)EdgeCNN過程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-04-04
Python使用Matplotlib實現(xiàn)Logos設(shè)計代碼
這篇文章主要介紹了Python使用Matplotlib實現(xiàn)Logos設(shè)計代碼,具有一定借鑒價值,需要的朋友可以參考下。2017-12-12
科學計算與數(shù)據(jù)分析利器Python數(shù)據(jù)分析庫Scipy使用詳解
Scipy在現(xiàn)代科學研究和數(shù)據(jù)分析中是一個不可或缺的庫,它建立在NumPy的基礎(chǔ)上,提供了更多的高級科學計算功能,包括優(yōu)化、信號處理、統(tǒng)計分析、插值、線性代數(shù)等,本文將會學習Scipy庫的各種功能和用法,包括數(shù)學優(yōu)化、統(tǒng)計分析、信號處理和插值等方面2023-11-11
pytorch 實現(xiàn)凍結(jié)部分參數(shù)訓練另一部分
這篇文章主要介紹了pytorch 實現(xiàn)凍結(jié)部分參數(shù)訓練另一部分,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03

