後端一個重要的點就是與數據庫聯繫,例如網頁的註冊、登陸,內容的更新等都須要與數據庫創建關係。以MySQL
數據庫爲例,平時咱們會用mysqldb(python 2)
或者pymysql(python 3)
去操做MySQL
數據庫,但這種方法也是須要本身編寫SQL語句的。如今咱們有了ORM模型,簡單來講,ORM是把數據庫中的表抽象成模型,表的列名對應模型的屬性,這樣咱們能夠調用類的屬性或方法去得到數據庫中的數據。例如假設MySQL
數據庫中有一張表名爲table1
,使用SELECT * FROM table1 WHERE id=1
獲取id
爲1
的數據,若是將表table1
映射成ORM模型Table
,那麼能夠直接使用Table.query.filter(id=1)
,這樣操做簡單了不少,也很利於理解。html
SQLAlchemy
就是一個這樣的ORM,咱們能夠直接安裝flask_sqlalchemy
來使用。在這以前咱們先在MySQL
中手動創建一個數據庫harp
,在創建的時候把charset
設置爲utf8
,避免存入中文時變成亂碼,而後在配置文件config.py
中填寫好數據庫的鏈接信息:python
HOST = "127.0.0.1" PORT = "3306" DB = "harp" USER = "root" PASS = "Your Password" CHARSET = "utf8" DB_URI = "mysql+pymysql://{}:{}@{}:{}/{}?charset={}".format(USER, PASS, HOST, PORT, DB, CHARSET) SQLALCHEMY_DATABASE_URI = DB_URI
SQLAlchemy
依賴mysqldb
或者pymysql
去鏈接數據庫和執行SQL語句,由於咱們用的是python 3
,因此須要在配置信息中指明使用pymysql
,若是是python 2
能夠省略,默認是使用mysqldb
。mysql
創建好了數據庫,咱們開始建表,首先創建一張用戶表,咱們設想它應該有id(做爲主鍵)、用戶名、密碼、註冊時間這些基本的字段,有了ORM,咱們就不用再寫SQL去建表了,在項目的主py文件中添加如下代碼:sql
from flask_sqlalchemy import SQLAlchemy from datetime import datetime import config app = Flask(__name__) app.config.from_object(config) db = SQLAlchemy(app) class Users(db.Model): __tablename__ = 'users_info' id = db.Column(db.Integer, primary_key=True, autoincrement=True) username = db.Column(db.String(32), nullable=False) password = db.Column(db.String(100), nullable=False) register_time = db.Column(db.DateTime, nullable=False, default=datetime.now()) db.create_all()
解讀一下這段代碼,導入SQLAlchemy
和含有數據庫鏈接信息的config
,實例化一個SQLAlchemy
對象名爲db
,其傳入的參數爲Flask
實例app
。接下來定義了一個User
類,這個類就是ORM中的模型,也就是數據庫中的表映射的模型,它須要繼承自db.Model
,__tablename__
這個屬性就是建表後,數據庫生成的表名;而後使用db.Column
來實例化id/username/password/register_time
這幾個列,db.Column
的參數描述列的類型、主鍵等信息,如db.Integer/db.String(32)/db.DateTime
分別表明整形、字符串(最大長度)、時間,primary_key=True
說明該字段爲主鍵,autoincrement=True
表明自增加,nullable
決定是否可爲空,default
表明默認值。最後用db.create_all()
來實現建立。咱們暫時不用理解爲什麼SQLAlchemy
須要傳入Flask
實例做爲參數,爲什麼模型要繼承自db.Model
,重要的是能夠先把想要的表創建起來。數據庫
進入數據庫,輸入desc user_info;
,咱們發現表已經創建好了,其結構圖以下:flask
但它如今仍是空的,咱們來試着插入一條語句,將視圖函數修改成:後端
@app.route('/') def index(): user = Users(username='Harp', password='123456') db.session.add(user) db.session.commit() return render_template('home.html')
代碼實例化一個Users
的對象user
,傳入username
和password
,使用db.session.add(user)
將其加入到數據庫的session
(能夠理解爲事務)中,而後使用db.session.commit()
提交。咱們運行程序,而後用瀏覽器訪問,瀏覽器正常顯示告終果,這時再看一眼數據庫,發現這條數據已經寫入到了數據庫:瀏覽器
查詢、修改數據也一樣很簡單:session
@app.route('/') def index(): user = Users.query.filter(Users.id == 1).first() #查找 print(user.username) user.username = 'Harp1207' #修改 db.session.commit() #修改後需提交 print(user.username) return render_template('home.html')
思考問題:
1.爲什麼要把模型的操做語句放在視圖函數中?(搜索上下文這個概念)
2.數據查找,咱們用的是Model.query
,其實還能夠用db.session.query
,二者有何區別?filter和filter_by又有何區別?app