Python的Flask架構中SQLAlchemy使用時的亂碼問題解決

來源:互聯網
上載者:User
一、問題

這兩天在學習使用flask + SQLAlchemy 定製一個web查詢頁面的demo ,在測試時,發現查詢到的結果顯示亂碼 。這裡將解決方案記錄下。

二、解決思路

1、flask 程式上定位

flask的文檔中提到可以通過設定SQLALCHEMY_NATIVE_UNICODE來禁止使用SQLAlchemy預設的Unicode編碼。有可能是SQLAlchemy預設的Unicode編碼不是UTF-8,抱著這樣的想法,在程式中指定了“SQLALCHEMY_NATIVE_UNICODE=False”,執行程式,報錯。

flask中還提到“use_native_unicode”為目標編碼來指定編碼方式,嘗試將“db = SQLAlchemy(app)”改為“db = SQLAlchemy(app, use_native_unicode="utf8")”。這回雖然沒報錯,但還是亂碼。

2、mysql 上定位

突然想到有可能是建表的時候,沒有指定字元集,使用的是資料庫預設的字元集的導致的。繼續找了一段時間的如何指定建表時使用字元集的方法,未果。

資料庫該不會使用的不是UTF-8吧?抱著這個想法,進入資料庫,輸入“status”,在輸出的資訊上顯示預設是latin-1。搞了半天,原來問題在這。

mysql> status--------------mysql Ver 14.14 Distrib 5.1.73, for redhat-linux-gnu (x86_64) using readline 5.1Connection id:     9Current database:   web12306Current user:      root@localhostSSL:          Not in useCurrent pager:     stdoutUsing outfile:     ''Using delimiter:    ;Server version:     5.1.73 Source distributionProtocol version:    10Connection:       Localhost via UNIX socketServer characterset:  utf8Db   characterset:  utf8Client characterset:  latin1Conn. characterset:  latin1UNIX socket:      /var/lib/mysql/mysql.sock

3、解決問題

即然找到了,問題就在mysql 的my.cnf 上增加相關配置,並重啟mysql 服務:

# 進入mysql的設定檔目錄cd /etc/mysql/# 編輯my.cnf設定檔vim my.cnf# 在檔案中的[mysqld]下面增加一行內容character_set_server = utf8# 在[client]和[mysql]下面分別增加一行內容default-character-set = utf8# 儲存。然後重啟MySQL的服務,設定就生效了service mysqld restart

註:需要注意的是,之前已經存在的資料,在上面修改過後,通過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, MetaDatafrom sqlalchemy.sql.expression import Castfrom sqlalchemy.ext.compiler import compilesfrom 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))#建立資料庫連接,MySQLdb串連方式mysql_db = create_engine('mysql://使用者名稱:密碼@ip:port/dbname')#建立資料庫連接,使用 mysql-connector-python串連方式#mysql_db = create_engine("mysql+mysqlconnector://使用者名稱:密碼@ip:port/dbname")#產生表metadata.create_all(mysql_db)#建立一個映射類class User(object):  pass#把表映射到類mapper(User, userTable)#建立了一個自訂了的 Session類Session = sessionmaker()#將建立的資料庫連接關聯到這個sessionSession.configure(bind=mysql_db)session = Session()def main():  u = User()  #給映射類添加以下必要的屬性,因為上面建立表指定這個欄位不可為空,且唯一  u.user_name='tan9le測試'  #按照上面建立表的相關代碼,這個欄位允許為空白  u.password='123456'  #在session中新增內容  session.add(u)  #儲存資料  session.flush()  #資料庫事務的提交,sisson自動到期而不需要關閉  session.commit()  #query() 簡單的理解就是select() 的支援 ORM 的替代方法,可以接受任意組合的 class/column 運算式  query = session.query(User)  #列出所有user  print list(query)  #根據主鍵顯示  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()  #列印會出現新密碼  print query.get(1).password  #根據id欄位排序,列印其中的使用者名稱和密碼  for instance in session.query(User).order_by(User.user_id):    print instance.user_name, instance.password  #釋放資源  session.close()if __name__ == '__main__':  main()
  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.