最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python的Flask框架中使用Flask-SQLAlchemy管理數(shù)據(jù)庫的教程

 更新時間:2016年06月14日 15:41:32   作者:ipython  
在Python中我們可以使用SQLAlchemy框架進行數(shù)據(jù)庫操作,那么對應(yīng)的在Flask框架中我們可以使用SQLAlchemy,下面我們就來看一下Python的Flask框架中使用Flask-SQLAlchemy管理數(shù)據(jù)庫的教程

使用Flask-SQLAlchemy管理數(shù)據(jù)庫
Flask-SQLAlchemy是一個Flask擴展,它簡化了在Flask應(yīng)用程序中對SQLAlchemy的使用。SQLAlchemy是一個強大的關(guān)系數(shù)據(jù)庫框架,支持一些數(shù)據(jù)庫后端。提供高級的ORM和底層訪問數(shù)據(jù)庫的本地SQL功能。
和其他擴展一樣,通過pip安裝Flask-SQLAlchemy:

(venv) $ pip install flask-sqlalchemy

在Flask-SQLAlchemy,數(shù)據(jù)庫被指定為URL。表格列出三個最受歡迎的數(shù)據(jù)庫引擎url的格式:

2016614153005287.png (482×148)

在這些URL中,hostname是指托管MySQL服務(wù)的服務(wù)器,可能是本地(localhost)又或是遠程服務(wù)器。數(shù)據(jù)庫服務(wù)器可以托管多個數(shù)據(jù)庫,所以database指出要使用的數(shù)據(jù)庫名。數(shù)據(jù)庫需要身份驗證,username和 password是數(shù)據(jù)庫用戶憑證。
注:> SQLite數(shù)據(jù)庫沒有服務(wù),所以hostname、username和password可以缺省且數(shù)據(jù)庫是一個磁盤文件名。
應(yīng)用程序數(shù)據(jù)庫URL必須在Flask配置對象中的SQLALCHEMY_DATABASE_URI鍵中進行配置。另一個有用的選項是SQLALCHEMY_COMMIT_ON_TEARDOWN,可以設(shè)置為True來啟用自動提交數(shù)據(jù)庫更改在每個請求中。查閱Flask-SQLAlchemy文檔獲取更多其他配置選項。

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)

由SQLAlchemy實例化的db對象表示數(shù)據(jù)庫且提供訪問Flask-SQLAlchemy的所有功能。


模型定義
模型是指由應(yīng)用程序使用的持久化實體。在ORM的背景下,一個模型通常是一個帶有屬性的Python類,其屬性與數(shù)據(jù)庫表的列相匹配對應(yīng)。Flask-SQLAlchemy數(shù)據(jù)庫實例提供了一個基類以及一組輔助類和函數(shù)用于定義它的結(jié)構(gòu)。

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):
  __tablename__ = '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__類變量定義數(shù)據(jù)庫中表的名稱。如果__tablename__缺省Flask-SQLAlchemy會指定默認的表名,但是這些缺省名稱不遵守使用復(fù)數(shù)命名的約定,所以最好是顯式命名表名。其余的變量是模型的屬性,被定義為db.Column類的實例。
傳給db.Column構(gòu)造函數(shù)的第一個參數(shù)是數(shù)據(jù)庫列的類型也就是模型屬性的數(shù)據(jù)類型。表格5-2列出一些可用的列的類型,也是用于模型中的Python類型。

2016614153056823.png (488×494)

最常見的SQLAlchemy列類型
db.Column剩余的參數(shù)為每個屬性指定了配置選項。

2016614153118002.png (489×192)

最常見的SQLAlchemy列選項
注:Flask-SQLAlchemy需要給所有的模型定義主鍵列,通常命名為id。
兩個模型都包含了repr()方法來給它們顯示一個可讀字符串,雖然不是完全必要,不過用于調(diào)試和測試還是很不錯的。

關(guān)系
關(guān)系數(shù)據(jù)庫通過使用關(guān)系在不同的表中建立連接。關(guān)系圖表達了用戶和用戶角色之間的簡單關(guān)系。這個角色和用戶是一對多關(guān)系,因為一個角色可以從屬于多個用戶,而一個用戶只能擁有一個角色。
下面的模型類展示了中表達的一對多關(guān)系。

class Role(db.Model): 
  # ...
  users = db.relationship('User', backref='role')

class User(db.Model): 
  # ...
  role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))

關(guān)系通過使用外鍵來連接兩行。添加給User模型的role_id列被定義為外鍵,且建立關(guān)系。db.ForeignKey()的參數(shù)roles.id指定的列應(yīng)該理解為在roles表的行中持有id值的列。
添加到Role模型的users屬性表現(xiàn)了關(guān)系的面向?qū)ο蟮挠^點。給定Role類的實例,users屬性會返回一組連接到該角色的用戶。指定給db.relationship()的第一個參數(shù)表明模型中關(guān)系的另一邊。如果類還未定義,這個模型可以作為字符串提供。
注意:之前在segmentdefault中遇到的問題,后來粗略閱讀了SQLAlchemy的源碼。ForeignKey類的column接收三種類型的參數(shù),一種是“模型名.屬性名”;一種是“表名.列名”,最后一種沒看明白,下次試著用一下。
db.relationship()的backref參數(shù)通過給User模型增加role屬性來定義反向關(guān)系。這個屬性可以替代role_id訪問Role模型,是作為對象而不是外鍵。
大多數(shù)情況下db.relationship()可以定位自己的外鍵關(guān)系,但是有時候不能確定哪個列被用作外鍵。例如,如果User模型有兩個或更多列被定義為Role的外鍵,SQLAlchemy將不知道使用兩個中的哪一個。每當外鍵配置模棱兩可的時候,就必須使用額外參數(shù)db.relationship()。下標列出一些常用配置選項用于定義關(guān)系:

常用SQLAlchemy關(guān)系選項

2016614153210518.png (570×292)

建議:如果你有克隆在GitHub上的應(yīng)用程序,你現(xiàn)在可以運行g(shù)it checkout 5a來切換到這個版本的應(yīng)用程序。
除了一對多關(guān)系還有其他種類關(guān)系。一對一關(guān)系可以表述為前面描述的一對多關(guān)系,只要將db.relationship()中的uselist選項設(shè)置為False,“多”就變?yōu)椤耙弧绷?。多對一關(guān)系也可表示為將表反轉(zhuǎn)后的一對多關(guān)系,或表示為外鍵和db.relationship()定義在“多”那邊。最復(fù)雜的關(guān)系類型,多對多,需要一個被稱作關(guān)聯(lián)表的額外表。你將在第十二章學(xué)習(xí)多對多關(guān)系。

數(shù)據(jù)庫操作
學(xué)習(xí)怎樣使用模型的最好方式就是使用Python shell。以下部分將介紹最常見的數(shù)據(jù)庫操作。

創(chuàng)建表

首先要做的第一件事情就是指示Flask-SQLAlchemy基于模型類創(chuàng)建數(shù)據(jù)庫。db.create_all()函數(shù)會完成這些:

(venv) $ python hello.py shell 
>>> from hello import db
>>> db.create_all()

如果你檢查應(yīng)用程序目錄,你會發(fā)現(xiàn)名為data.sqlite的新文件,SQLite數(shù)據(jù)庫名在配置中給出。如果數(shù)據(jù)庫已存在db.create_all()函數(shù)不會重新創(chuàng)建或更新數(shù)據(jù)庫表。這會非常的不方便當模型被修改且更改需要應(yīng)用到現(xiàn)有的數(shù)據(jù)庫時。更新現(xiàn)有的數(shù)據(jù)庫表的蠻力解決方案是先刪除舊的表:

>>> db.drop_all()
>>> db.create_all()

不幸的是,這種方法有個不受歡迎的副作用就是摧毀舊的數(shù)據(jù)庫中的所有數(shù)據(jù)。更新數(shù)據(jù)庫問題的解決方案會在這章快結(jié)束的時候介紹。

插入行

下面的示例會創(chuàng)建新的角色和用戶:

>>> from hello import Role, User
>>> admin_role = Role(name='Admin')
>>> mod_role = Role(name='Moderator')
>>> user_role = Role(name='User')
>>> user_john = User(username='john', role=admin_role) 
>>> user_susan = User(username='susan', role=user_role) 
>>> user_david = User(username='david', role=user_role)

模型的構(gòu)造函數(shù)接受模型屬性的初始值作為關(guān)鍵字參數(shù)。注意,甚至可以使用role屬性,即使它不是一個真正的數(shù)據(jù)庫列,而是一對多關(guān)系的高級表示。這些新對象的id屬性沒有顯式設(shè)置:主鍵由Flask-SQLAlchemy來管理。到目前為止對象只存于Python中,他們還沒有被寫入數(shù)據(jù)庫。因為他們的id值尚未分配:

>>> print(admin_role.id) None
>>> print(mod_role.id) None
>>> print(user_role.id) None

修改數(shù)據(jù)庫的操作由Flask-SQLAlchemy提供的db.session數(shù)據(jù)庫會話來管理。準備寫入到數(shù)據(jù)庫中的對象必須添加到會話中:

>>> db.session.add(admin_role)
>>> db.session.add(mod_role)
>>> db.session.add(user_role)
>>> db.session.add(user_john)
>>> db.session.add(user_susan)
>>> db.session.add(user_david)

或,更簡潔的:

>>> db.session.add_all([admin_role, mod_role, user_role,
...   user_john, user_susan, user_david])
為了寫對象到數(shù)據(jù)庫,需要通過它的commit()方法來提交會話:
>>> db.session.commit()

再次檢查id屬性;這個時候它們都已經(jīng)被設(shè)置好了:

>>> print(admin_role.id) 
1
>>> print(mod_role.id)
2
>>> print(user_role.id) 
3

注:db.session數(shù)據(jù)庫會話和第四章討論的Flask會話沒有任何聯(lián)系。數(shù)據(jù)庫會話也叫事務(wù)。
數(shù)據(jù)庫會話在數(shù)據(jù)庫一致性上是非常有用的。提交操作會原子性地將所有添加到會話中的對象寫入數(shù)據(jù)庫。如果在寫入的過程發(fā)生錯誤,會將整個會話丟棄。如果你總是在一個會話提交相關(guān)修改,你必須保證避免因部分更新導(dǎo)致的數(shù)據(jù)庫不一致的情況。

注:數(shù)據(jù)庫會話也可以回滾。如果調(diào)用db.session.rollback(),任何添加到數(shù)據(jù)庫會話中的對象都會恢復(fù)到它們曾經(jīng)在數(shù)據(jù)庫中的狀態(tài)。
修改行

數(shù)據(jù)庫會話中的add()方法同樣可以用于更新模型。繼續(xù)在同一shell會話中,下面的示例重命名“Admin”角色為“Administrator”:

>>> admin_role.name = 'Administrator'
>>> db.session.add(admin_role)
>>> db.session.commit()

注意:不過貌似我們在做更新操作的時候都不使用db.session.add(),而是直接使用db.session.commit()來提交事務(wù)。
刪除行

數(shù)據(jù)庫會話同樣有delete()方法。下面的示例從數(shù)據(jù)庫中刪除“Moderator”角色:

>>> db.session.delete(mod_role)
>>> db.session.commit()

注意刪除,和插入更新一樣,都是在數(shù)據(jù)庫會話提交后執(zhí)行。

返回行

Flask-SQLAlchemy為每個模型類創(chuàng)建一個query對象。最基本的查詢模型是返回對應(yīng)的表的全部內(nèi)容:

>>> Role.query.all()
[<Role u'Administrator'>, <Role u'User'>]
>>> User.query.all()
[<User u'john'>, <User u'susan'>, <User u'david'>]

使用過濾器可以配置查詢對象去執(zhí)行更具體的數(shù)據(jù)庫搜索。下面的例子查找所有被分配“User”角色的用戶:

>>> User.query.filter_by(role=user_role).all()
[<User u'susan'>, <User u'david'>]

對于給定的查詢還可以檢查SQLAlchemy生成的原生SQL查詢,并將查詢對象轉(zhuǎn)換為一個字符串:

>>> str(User.query.filter_by(role=user_role))
'SELECT users.id AS users_id, users.username AS users_username,
users.role_id AS users_role_id FROM users WHERE :param_1 = users.role_id'

如果你退出shell會話,在前面的示例中創(chuàng)建的對象將不能作為Python對象而存在,但可繼續(xù)作為行記錄存在各自的數(shù)據(jù)庫表中。如果你開始一個全新的shell會話,你必須從它們的數(shù)據(jù)庫行中重新創(chuàng)建Python對象。下面的示例執(zhí)行查詢來加載名字為“User”的用戶角色。

>>> user_role = Role.query.filter_by(name='User').first()

過濾器如filter_by()通過query對象來調(diào)用,且返回經(jīng)過提煉后的query。多個過濾器可以依次調(diào)用直到需要的查詢配置結(jié)束為止。

下面展示一些查詢中常用的過濾器。

2016614153423667.png (516×198)

在需要的過濾器已經(jīng)全部運用于query后,調(diào)用all()會觸發(fā)query執(zhí)行并返回一組結(jié)果,但是除了all()以外還有其他方式可以觸發(fā)執(zhí)行。常用SQLAlchemy查詢執(zhí)行器:

2016614153439331.png (560×224)

關(guān)系的原理類似于查詢。下面的示例從兩邊查詢角色和用戶之間的一對多關(guān)系:

>>> users = user_role.users
>>> users
[<User u'susan'>, <User u'david'>]
>>> users[0].role
<Role u'User'>

此處的user_role.users查詢有點小問題。當user_role.users表達式在內(nèi)部調(diào)用all()時通過隱式查詢執(zhí)行來返回用戶的列表。因為查詢對象是隱藏的,是不可能通過附加查詢過濾器進一步提取出來。在這個特定的例子中,它可能是用于按字母排列順序返回用戶列表。在下面的示例中,被lazy = 'dynamic'參數(shù)修改過的關(guān)系配置的查詢是不會自動執(zhí)行的。

app/models.py:動態(tài)關(guān)系

class Role(db.Model): 
  # ...
  users = db.relationship('User', backref='role', lazy='dynamic') 
  # ...

用這種方式配置關(guān)系,user_roles.user查詢還沒有執(zhí)行,所以可以給它增加過濾器:

>>> user_role.users.order_by(User.username).all()
[<User u'david'>, <User u'susan'>]
>>> user_role.users.count()
2

相關(guān)文章

  • Python實現(xiàn)雙向鏈表

    Python實現(xiàn)雙向鏈表

    這篇文章主要為大家詳細介紹了Python實現(xiàn)雙向鏈表,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • django框架防止XSS注入的方法分析

    django框架防止XSS注入的方法分析

    這篇文章主要介紹了django框架防止XSS注入的方法,結(jié)合實例形式分析了XSS攻擊的原理及Django框架防止XSS攻擊的相關(guān)操作技巧,需要的朋友可以參考下
    2019-06-06
  • python通過exifread模塊獲得圖片exif信息的方法

    python通過exifread模塊獲得圖片exif信息的方法

    這篇文章主要介紹了python通過exifread模塊獲得圖片exif信息的方法,實例分析了Python操作exifread模塊的技巧,需要的朋友可以參考下
    2015-03-03
  • Python 工具類實現(xiàn)大文件斷點續(xù)傳功能詳解

    Python 工具類實現(xiàn)大文件斷點續(xù)傳功能詳解

    用python進行大文件下載的時候,一旦出現(xiàn)網(wǎng)絡(luò)波動問題,導(dǎo)致文件下載到一半。如果將下載不完全的文件刪掉,那么又需要從頭開始,如果連續(xù)網(wǎng)絡(luò)波動,是不是要頭禿了。本文提供斷點續(xù)傳下載工具方法,希望可以幫助到你
    2021-10-10
  • 使用pandas模塊實現(xiàn)數(shù)據(jù)的標準化操作

    使用pandas模塊實現(xiàn)數(shù)據(jù)的標準化操作

    這篇文章主要介紹了使用pandas模塊實現(xiàn)數(shù)據(jù)的標準化操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • Python?Plotly庫安裝及使用教程

    Python?Plotly庫安裝及使用教程

    這篇文章主要介紹了包括安裝、導(dǎo)入庫、Plotly的基本結(jié)構(gòu)、常見圖表類型、樣式定制以及如何與Pandas數(shù)據(jù)框結(jié)合使用,通過示例代碼和解釋,幫助讀者快速掌握Plotly的使用技巧,需要的朋友可以參考下
    2025-03-03
  • python 判斷txt每行內(nèi)容中是否包含子串并重新寫入保存的實例

    python 判斷txt每行內(nèi)容中是否包含子串并重新寫入保存的實例

    這篇文章主要介紹了python 判斷txt每行內(nèi)容中是否包含子串并重新寫入保存的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • 將string類型的數(shù)據(jù)類型轉(zhuǎn)換為spark rdd時報錯的解決方法

    將string類型的數(shù)據(jù)類型轉(zhuǎn)換為spark rdd時報錯的解決方法

    今天小編就為大家分享一篇關(guān)于將string類型的數(shù)據(jù)類型轉(zhuǎn)換為spark rdd時報錯的解決方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • 7個實用的Python自動化代碼別再重復(fù)造輪子了

    7個實用的Python自動化代碼別再重復(fù)造輪子了

    關(guān)于Python有一句名言:不要重復(fù)造輪子,給大家分享經(jīng)過Python3.6.4調(diào)試通過的代碼,感興趣的朋友跟隨小編一起看看吧
    2023-11-11
  • pytorch:實現(xiàn)簡單的GAN示例(MNIST數(shù)據(jù)集)

    pytorch:實現(xiàn)簡單的GAN示例(MNIST數(shù)據(jù)集)

    今天小編就為大家分享一篇pytorch:實現(xiàn)簡單的GAN示例(MNIST數(shù)據(jù)集),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-01-01

最新評論

北安市| 黄平县| 隆昌县| 原阳县| 太原市| 东源县| 孝感市| 安顺市| 成安县| 岢岚县| 长乐市| 洪江市| 错那县| 景洪市| 永登县| 监利县| 鸡西市| 广南县| 衡阳市| 洪湖市| 沽源县| 广汉市| 泰宁县| 文山县| 武乡县| 平顶山市| 当阳市| 哈密市| 陆丰市| 河北区| 京山县| 大兴区| 兴化市| 石河子市| 丹东市| 内黄县| 望城县| 石阡县| 横山县| 饶河县| 什邡市|