Python-Web框架之 - 利用SQLALchemy創(chuàng)建與數(shù)據(jù)庫MySQL的連接, 詳解用Flask時會遇到的一些大坑 !
經(jīng)過這個小項目算是對Django與Flask這兩個web框架有了新的認識 , Django本身的輪子非常齊全 , 套路也很固定 , 新手在接觸Django框架時 , 不會陷入到處找輪子的大坑 ;
那么在使用Flask這個框架的時候會碰到哪些大坑呢 , 首先Flask是一個輕量級的web框架 , 之所以說它輕量級是因為它本身并沒有多少輪子 , 那是不是就代表這些輪子需要我們自己來造呢 , 那倒不必 , 但是需要我們?nèi)フ疫@些輪子 , 這恰恰是鍛煉你的思維的時候 , 你要找輪子之前 , 你必須得知道需要哪些輪子 , 這些輪子起到什么作用 , 知道了這些之后 , 進行下一步 ;
重點來了 , 這里所說的輪子到底是指什么呢 , 為什么說它坑呢 , Flask這個框架的文檔和資料遠沒有Django那么豐富和清晰 , 你可能在網(wǎng)上能找到一些看似是你需要的資料 , 但是它很有可能里面用到的模塊、驅(qū)動會有各種版本不一致的大坑 , 從東拼西湊來的輪子弄到一起可能會出現(xiàn)各種報錯 , 這個時候你就得一個報錯一個報錯的解決 , 去查這個報錯的原因 , 去查東拼西湊的模塊的文檔說明 , 這里要用到的MySQL驅(qū)動就有很多種版本 , PyMySQL、MySQLdb、mysql-connector、mysql-connector-python , 如果你選擇MySQLdb , 那恭喜你這個是python2.x的版本 , 如果你選擇了mysql-connector-python , 那又要恭喜你 ,這個只支持到python3.4 哈哈 , 如果選擇PyMySQL , 雖然程序可以運行 , 但是會有各種警告之類的長串的紅色字體 , 看著就很煩 , 經(jīng)過實測選擇mysql-connector不會有什么問題 ;
另外 , 還有一些使用數(shù)據(jù)庫增刪改查語句的坑 , 數(shù)據(jù)庫語句可不像python語句那么干凈 , 有些語句末尾要加分號 , 有些末尾又不需要加 , 有時候甚至還有對象單數(shù)和復數(shù)的區(qū)別 , 稍不留神兒你的語句就沒效果或者報錯 .
最后直接上源碼和一些筆記吧...
# coding=utf-8 from flask import Flask # SQLALchemy可以理解為python和數(shù)據(jù)庫之間關(guān)聯(lián)的工具 from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) # 配置數(shù)據(jù)庫的地址URI , 格式 "數(shù)據(jù)庫類型+數(shù)據(jù)庫驅(qū)動名稱://用戶名:密碼@機器地址:端口號/數(shù)據(jù)庫名" , 端口號可以不寫. # python3中用的mysql驅(qū)動是mysql-connector , 已經(jīng)不支持python2的MySQLdb驅(qū)動. app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+mysqlconnector://root:password@127.0.0.1/sql_demo" # 跟蹤數(shù)據(jù)庫的修改 --> 不建議開啟 , 一是消耗性能 , 二是未來的版本中會移除. app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False # 將app作為參數(shù)傳入這個關(guān)聯(lián)工具 , 創(chuàng)建一個兩者相關(guān)聯(lián)對象db db = SQLAlchemy(app) # 創(chuàng)建數(shù)據(jù)庫的模型 , 需要繼承db.Model模型 class Role(db.Model): """創(chuàng)建角色類""" # 定義表名 __tablename__ = "roles" # 定義字段 # db.Column表示是一個字段 , db.Integer就代表id這個字段的數(shù)據(jù)類型是整數(shù) , primary_key代表主鍵 , 是作為表的行的唯一標識. # db.String代表是字符串類型 , 字符串長度定義個n個字節(jié) , unique(唯一的) , unique=True代表這列不允許出現(xiàn)重復的值 id = db.Column(db.Integer,primary_key=True) name = db.Column(db.String(100),unique=True) # 在"一對多"的一中定義users_role屬性 , 該屬性不會出現(xiàn)在字段中 , 后面的backref="role"是給User反向引用的 # 由于是"一對多" , 所以"多"的地方用User參數(shù) , "一"的地方用不加s的實例對象參數(shù)role users_role = db.relationship("User",backref="role") def __repr__(self): """返回定制對象輸出信息 , 與__str__作用類似""" return "Role:%d %s"%(self.id,self.name) class User(db.Model): """創(chuàng)建用戶類""" __tablename__ = "users" id = db.Column(db.Integer,primary_key=True) name = db.Column(db.String(100),unique=True) password = db.Column(db.String(100)) # 每個人的密碼不要求不同 , 可以不用指定unique=True email = db.Column(db.String(100),unique=True) role_id = db.Column(db.Integer,db.ForeignKey("roles.id")) # db.ForeignKey定義外鍵 , 參數(shù)是 表名.id def __repr__(self): """返回定制對象輸出信息 , 與__str__作用類似""" return "User:%d %s %s %s"%(self.id,self.name,self.password,self.email) # 定義創(chuàng)建role和user實例對象的函數(shù). def role_user_make(): role1 = Role(name="admin") role2 = Role(name="user") db.session.add_all([role1,role2]) db.session.commit() user1 = User(name="Tom", password="XYZ456", email="tom@163.com", role_id=role1.id) user2 = User(name="Jack", password="CB_4321", email="jack@163.com", role_id=role2.id) user3 = User(name="Alan", password="Zj@321", email="alan@163.com", role_id=role2.id) user4 = User(name="Mark", password="111222", email="mark@163.com", role_id=role2.id) db.session.add_all([user1,user2,user3,user4]) db.session.commit() @app.route("/") def index(): return "hello world" if __name__ == '__main__': # 刪除表 , 在創(chuàng)建表之前先刪除表 db.drop_all() # 創(chuàng)建表 db.create_all() role_user_make() app.run(debug=True)



浙公網(wǎng)安備 33010602011771號