本文內容:
1.使用Flask-SQLAlchemy管理數據庫
2.定義模型
3.關系
使用Flask-SQLAlchemy管理數據庫
Flask-SQLAlchemy是一個Flask擴展,簡化Flask程序使用SQLAlchemy的操作,首先我們在pycharm中安裝這個插件。
在Flask-SQLAlchemy中,數據庫使用URL指定。下圖列出幾個常用的數據庫。
數據庫引擎 | URL |
---|---|
MySQL | mysql://username:password@hostname/database |
Postgres | postgresql://username:password@hostname/database |
SQLite(Unix) | sqlite:////absolute/path/to/database |
SQLite(Windows) | sqlite:///c:/absolute/path/to/database |
上述URL中,hostname表示MySQL服務所在的主機,可以是本地主機(localhost),也可以是遠程服務器。數據庫服務器上可以托管多個數據庫,所以database表示要使用的數據庫名。username和password表示數據庫用戶名和密碼。SQLite數據庫不需要使用服務器,因此不用指定hostname、username和password。URL中的database是硬盤上文件的文件名。
URL必須保存到Flask配置對象的SQLALCHEMY_DATABASE_URI鍵中。配置對話中的SQLALCHEMY_COMMIT_ON_TEARDOWN鍵設置為True時,每次請求結束后都會自動提交數據庫中的變動。
修改hello.py,配置數據庫
from flask.ext.sqlalchemy import SQLAlchemy
basedir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///'+os.path.join(basedir,'data.sqlite')
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
db = SQLAlchemy(app)
db對象是SQLAlchemy類的實例,表示程序使用的數據庫,同時還獲得了Flask-SQLAlchemy提供的所有功能。
定義模型
在ORM中,模型一般是一個Python類,類中的屬性對應數據表中的列。

修改hello.py,定義上圖中的Role和User模型(表)
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(64),unique=True)
def __repr__(self):
return '<Role %r>' % self.name
class User(db.Model):
__teblename__ = 'users'
id = db.Column(db.Integer,primary_key=True)
username = db.Column(db.String(64),unique=True,index=True)
def __repr__(self):
return '<User %r>' % self.username
類變量tablename是數據庫中使用的表名,如果不定義,flask會使用一個默認的名字。其余的類變量都是該模型的屬性,被定義為db.Column類的實例。
db.Column類構造函數的第一個參數是數據庫列和模型屬性的類型,下圖為一些可用的列類型以及在模型中使用的Python類型。

db.Column中其余的參數指定屬性的配置選項如下圖

Flask-SQLAlchemy要求每個模型都要定義主鍵,一般命名為id。
上面兩個模型都定義了repr()方法,返回一個具有可讀性的字符串表示模型,可在調試和測試時使用。
關系
關系型數據庫使用關系把不同表中的行聯系起來。
修改hello.py,表示一對多關系
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(64),unique=True)
users = db.relationship('User',backref='role')
def __repr__(self):
return '<Role %r>' % self.name
class User(db.Model):
__teblename__ = 'users'
id = db.Column(db.Integer,primary_key=True)
username = db.Column(db.String(64),unique=True,index=True)
role_id = db.Column(db.Integer,db.ForeignKey('roles.id'))
關系使用users表中的外鍵連接了兩行。添加到User模型中的role_id列被定義為外鍵。它傳遞給db.ForeignKey()的參數'roles.id'表明,這列的值是roles表中行的id值。
添加到role模型中的users屬性代表這個關系的面向對象視角。對于一個role類的實例,其users屬性將返回與角色相關聯的用戶組成的列表。db.relationship()的第一個參數表明這個關系的另一端是哪個模型。如果模型類尚未定義,可使用字符串形式指定。
db.relationship()中的backref參數向User模型中添加一個role屬性,從而定義反向關系。這一屬性可替代role_id訪問role模型,此時獲取的是模型對象,而不是外鍵的值。
大多數情況下,db.relationship()都能自行找到關系中的外鍵,但有時卻無法決定把哪一列作為外鍵。例如如果User模型中有兩個或以上的列定義為role模型的外鍵,SQLAlchemy就不知道該用哪個。如果無法決定外鍵,你就要為db.relationship()提供額外參數,確定使用外鍵,下圖列出定義關系時常用的配置選項。


除了一對多外,一對一類型可以用一對多關系表示,但調用db.relationship()時要把uselist設為False,把“多”變為“一”。多對一關系也可以用一對多表示,對調兩個表即可,或者把外鍵和db.relationship()都放在“多”這一側。多對多關系以后再說。