標籤:選項 進位 擴充 重啟 code 串連 local mysqld UI
上一章實現了登入的部分功能,之所以說是部分功能,是因為使用者名稱和密碼寫成固定值肯定是不可以的,一個整體的功能,至少需要註冊,登入,密碼修改等,這就需要提供一個把這些值儲存到資料庫的能力。
當前的主流資料庫分為兩種,即關聯式資料庫和NoSql資料庫,對於中小型的系統來說,兩種資料庫效能,易用性都相當,都是很好的選擇。
基礎配置
這裡使用SQLAlchemy資料庫架構的flask整合套件,即flask-SQLAlchemy來進行資料庫操作。
SQLAlchemy是一個非常好的架構,簡化了資料庫的操作,即提供了高層次的ORM,也提供了低層次的SQL功能,使用起來非常方便。
安裝方式與之前類型,還是pip命令:
pip3.6 install flask-sqlalchemy
安裝完成之後,對default的配置部分進行修改,首先匯入包:
from flask.ext.sqlalchemy import SQLAlchemy
然後配置連結字串:
app.config["SQLALCHEMY_DATABASE_URI"]=‘mysql://root:[email protected]/cblog‘
配置請求結束後更改自動認可:
app.config["SQLALCHEMY_COMMIT_ON_TEARDOWN"]=True
執行個體化SQLAlchemy:
db=SQLAlchemy(app)
模型設定
安裝完成之後,繼續完善登入的例子,修改default.py檔案,新增User模型(類)和Role模型(以示關聯)
Role類
class Role(db.Model): #需繼承模型 __tablename__="roles" #db中表明,如果不設定,則會與class同的預設名 id=db.Column(db.Integer,primary_key=True) #SQLAlchemy要求必須有主鍵,一般命名為id即可 name=db.Column(db.String(50),unique=True) #表示name為字串,不重複 users=db.relationship("User",backref=‘role‘) #關聯user模型,並在user中添加反向引用(backref)
User類
class User(db.Model): __tablename__="users" id=db.Column(db.Integer,primary_key=True) username=db.Column(db.String(50),unique=True,index=True) #此列帶索引 password=db.Column(db.String(50)) role_id=db.Column(db.Integer,db.ForeignKey("roles.id")) #外鍵指向roles表中的id列
下面要考慮如何執行,要既方便,有不能入侵到邏輯代碼,這就要求不能寫入程式碼到邏輯代碼中,比如把判斷db狀態的代碼作為參數傳遞給app.run(),這時候shell就派上了用場
配置指令碼
想讓flask支援命令列指令碼,首先需要安裝flask-script擴充:
pip3.6 install flask-script
修改default.py的代碼:
from flask.ext.script import Managermamager=Manager(app)....if __name__==‘__main__‘: #app.run(debug=True) mamager.run()
修改過之後,再次運行:
python default.py
發現並沒有成功運行,而是有提示:
可以看到,後邊需要參數,分別為shell(執行指令碼),runserver(啟動服務)和協助
下邊啟動服務:
python default.py runserver
服務成功執行
資料庫更多配置
但這個時候,訪問網站(127.0.0.1:5000),會出現500錯誤,提示沒有mysql模組,這是為什麼呢?很明顯是沒有安裝mysql驅動的原因,使用pip命令安裝驅動:
pip3.6 install MySQL-python
發現出現錯誤,顯示內容為(此處僅為win系統):
根據提示,安裝c++的工具包,按照提示上的
http://landinghub.visualstudio.com/visual-cpp-build-tools
下載完成直接為exe檔案,安裝
重啟後安裝MySQL-python,發現還是不可以,經百度後才發現,MySQLdb這個庫最高只支援到python2.7,不在支援3.x,那隻好用其他辦法,使用PyMySQL庫:
pip3.6 install PyMySQL
然後修改default.py的代碼,增加兩行:
import pymysqlpymysql.install_as_MySQLdb()
進入源碼,注意這一行:
sys.modules["MySQLdb"] = sys.modules["_mysql"] = sys.modules["pymysql"]
即可成功使用並串連mysql。
瀏覽器輸入串連,正確進入網站。
接下來,使用shell建立資料庫表,進入default.py根目錄:
python default.py shellfrom default import dbdb.create_all()
這時候如果沒有報錯,那麼資料庫表應該建立完成:
資料庫遷移
那麼問題來了,這時候,對模型進行修改,是不會反應到db中的,那麼如果修改怎麼辦呢?對於當前來說,也很簡單:
db.drop_all()db.create_all()
但這個僅僅是現在調試時候使用,如果db中已經有了資料,則這個肯定是無法忍受的,這時候,就輪到資料庫遷移外掛程式Migrate登場了,首先還是一樣,需要進行安裝:
pip3.6 install flask-migrate
和之前一樣,安裝完之後修改default.py檔案進行配置:
from flask.ext.migrate import Migrate,MigrateCommandmigrate=Migrate(app,db) #配置遷移mamager.add_command("db",MigrateCommand) #配置遷移命令
然後使用init命令初始化遷移倉庫
python default.py db init
命令列顯示:
然後增加migrations目錄:
表示遷移檔案已經初始化完成。
migrate架構提供了一些命令來進行遷移操作,分別為(使用default.py檔案舉例):
#根據差異建立遷移python default.py db migrate -m "說明"#改動差異 python default.py db upgrade#取消差異改動python default.py db downgrade
回到表單
接下來看看登入如何與資料庫關聯起來,修改login方法內的代碼:
@app.route("/login",methods=["POST"])def loginPost(): username=request.form.get("username","") password=request.form.get("password","") user=User.query.filter_by(username=username,password=password).first() #資料庫查詢 if user is not None: session["user"]=username return render_template("/index.html",name=username,site_name=‘myblog‘) else: flash("您輸入的使用者名稱或密碼錯誤") return render_template("/login.html") #返回的仍為登入頁
執行結果非常完美。
一些總結
下面是一些關於python和db相連的總結性的東西
資料類型
| db類型(SQLAlchemy) |
python類型 |
| Integer |
int |
| SmallInteger |
int |
| BigInteger |
long |
| Float |
float |
| Numeric |
decimal.Decimal |
| String |
str |
| Text |
str |
| Boolean |
bool |
| Date |
datetime.date |
| Time |
datetime.time |
| DateTime |
datetime.datetime |
| PickleType |
python對象序列化 |
| LargeBinary |
str(二進位) |
列選項
| primary_key |
True為主鍵(每個對象至少一列) |
| unique |
True為不允許重複 |
| index |
True為建立索引 |
| nullable |
True為可為空白,false為不許為空白 |
| default |
設定預設值 |
| backref |
為另一模型添加反向引用 |
| primaryjoin |
明確兩個模型直接的連結條件 |
| lazy |
可選值:select:首次訪問時載入,immediate:來源物件載入後立即載入,joined使用連接立即載入,subquery:使用子查詢立即載入,noload:永不載入,dynamic:不載入記錄,但提供載入的查詢 |
| uselist |
如果為false,則不使用列表,而使用用標量值 |
| order_by |
排序方式 |
| secondary |
多對多時指定關係表的名字 |
| secondaryjoin |
手動設定多對多關係中二級連接條件 |
資料庫操作
| db.session.add(model) |
插入或修改記錄(需commit) |
| db.session.delete(model) |
刪除記錄(需commit) |
| model.query |
查詢記錄 |
查詢過濾器
| all() |
返回全部記錄 |
| filter() |
將過濾器添加至原查詢,返回新結果 |
| filter_by() |
將等值過濾器添加至原查詢,返回新結果 |
| limit() |
限制結果數量,分頁用 |
| offset() |
位移結果,分頁用 |
| order_by() |
排序 |
| group_by() |
分組 |
| first() |
返回首結果,沒有則返回None |
| first_or_404() |
返回首結果,沒有則返回404響應 |
| get() |
返回主鍵對應的記錄,沒有則返回None |
| get_or_404() |
返回主鍵對應的記錄,沒有則返回404響應 |
| count() |
返回全部數量 |
| paginate() |
返回Paginate對象,它包含指定範圍內的結果 |
|
經過這幾章,登入功能已經基本完成,在下一章中將講解使用者註冊的相關功能。
一個web應用的誕生(4)