python架構之Flask基礎篇(二)-------- 資料庫的操作

來源:互聯網
上載者:User

標籤:網上   model   引入   使用者   根據   prim   增刪改   sql   contain   

1.flask串連資料庫的四步:
  1. 倒入第三方資料庫擴充包:from flask_sqlalchemy import SQLAlchemy
  2. 配置config屬性,串連資料庫:

    app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:[email protected]/first_flask"
    app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False

  3. 建立資料庫first_flask
  4. 建立操作資料庫對象:db = SQLAlchemy(app)

下面直接上代碼解釋:

 

# -*- coding:utf-8 -*-from flask import Flaskfrom flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)# url的格式為:資料庫的協議://使用者名稱:密碼@ip地址:連接埠號碼(預設可以不寫)/資料庫名app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:[email protected]/first_flask"# 動態追蹤資料庫的修改. 效能不好. 且未來版本中會移除. 目前只是為瞭解決控制台的提示才寫的app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False# 建立資料庫的操作對象db = SQLAlchemy(app)class Role(db.Model):    __tablename__ = "roles"    id = db.Column(db.Integer,primary_key=True)    name = db.Column(db.String(16),unique=True)    # 給Role類建立一個uses屬性,關聯users表。    # backref是反向的給User類建立一個role屬性,關聯roles表。這是flask特殊的屬性。    users = db.relationship(‘User‘,backref="role")    # 相當於__str__方法。    def __repr__(self):        return "Role: %s %s" % (self.id,self.name)class User(db.Model):    # 給表重新定義一個名稱,預設名稱是類名的小寫,比如該類預設的表名是user。    __tablename__ = "users"    id = db.Column(db.Integer,primary_key=True)    name = db.Column(db.String(16),unique=True)    email = db.Column(db.String(32),unique=True)    password = db.Column(db.String(16))    # 建立一個外鍵,和django不一樣。flask需要指定具體的欄位建立外鍵,不能根據類名建立外鍵    role_id = db.Column(db.Integer,db.ForeignKey("roles.id"))    def __repr__(self):        return "User: %s %s %s %s" % (self.id,self.name,self.password,self.role_id)@app.route(‘/‘)def hello_world():    return ‘Hello World!‘if __name__ == ‘__main__‘:    # 刪除所有的表    db.drop_all()    # 建立表    db.create_all()    ro1 = Role(name = "admin")    # 先將ro1對象添加到會話中,可以復原。    db.session.add(ro1)        ro2 = Role()    ro2.name = ‘user‘    db.session.add(ro2)    # 最後插入完資料一定要提交    db.session.commit()    us1 = User(name=‘wang‘, email=‘[email protected]‘, password=‘123456‘, role_id=ro1.id)    us2 = User(name=‘zhang‘, email=‘[email protected]‘, password=‘201512‘, role_id=ro2.id)    us3 = User(name=‘chen‘, email=‘[email protected]‘, password=‘987654‘, role_id=ro2.id)    us4 = User(name=‘zhou‘, email=‘[email protected]‘, password=‘456789‘, role_id=ro1.id)    us5 = User(name=‘tang‘, email=‘[email protected]‘, password=‘158104‘, role_id=ro2.id)    us6 = User(name=‘wu‘, email=‘[email protected]‘, password=‘5623514‘, role_id=ro2.id)    us7 = User(name=‘qian‘, email=‘[email protected]‘, password=‘1543567‘, role_id=ro1.id)    us8 = User(name=‘liu‘, email=‘[email protected]‘, password=‘867322‘, role_id=ro1.id)    us9 = User(name=‘li‘, email=‘[email protected]‘, password=‘4526342‘, role_id=ro2.id)    us10 = User(name=‘sun‘, email=‘[email protected]‘, password=‘235523‘, role_id=ro2.id)    db.session.add_all([us1, us2, us3, us4, us5, us6, us7, us8, us9, us10])    db.session.commit()    app.run(debug=True)

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

下面插播一條bug:

當把表格建立完成,注釋這兩句話:

 # 刪除所有的表    db.drop_all()    # 建立表    db.create_all()

然後向表格裡面插入資料,此時會出現這樣的錯誤:

sqlalchemy.exc.IntegrityError: (_mysql_exceptions.IntegrityError) (1062, "Duplicate entry ‘admin‘ for key ‘name‘") [SQL: u‘INSERT INTO roles (name) VALUES (%s)‘] [parameters: (‘admin‘,)]

查了網上的好多資料說把欄位的約束unique=True去掉就好了,但是根本原因不在這。

原因就是因為app.run(debug=True)。開啟debug模式之後,當我們修改代碼的時候,比如將刪除表和建立表這兩句話注釋,然後開啟插入資料的注釋。這個過程debug模式預設就已經把程式運行一遍了。此時資料庫就已經有了資料,當我們再次手動執行的時候,又往資料庫中插入了一條資料,這時候就會報錯。因為欄位的約束是唯一性的unique,所以解決的辦法有兩種:

第一種:就是不要將刪除表和建立表這兩句話注釋,每次執行都要帶著這兩個句話。無論是debug模式自動執行還是我們手動執行程式,都會先刪除表然後再建立表,所以執行多少次都不怕。

第二種:關閉debug模式。就是這樣app.run()

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2.資料庫的增刪改查:

1.以下的方法都是返回一個新的查詢,需要配合執行器使用。

filter(): 過濾,功能比較強大。
filter_by():過濾,用在一些比較簡單的過濾情境。

order_by():排序。預設是升序,降序需要導包:from sqlalchemy import * 。然後引入desc方法。比如order_by(desc("email")).按照郵箱字母的降序排序。

 

group_by():分組。

2.以下都是一些常用的執行器:配合上面的過濾器使用。

get():獲得id等於幾的函數。比如:查詢id=1的對象。get(1)。切記:括弧裡沒有“id=”,直接傳入id的數值就ok。因為該函數的功能就是查詢主鍵等於幾的對象。

all():查詢所有的資料。

first():查詢第一個資料。

count():返回查詢結果的數量。

paginate():分頁查詢,返回一個分頁對象。paginate(參數1,參數2,參數3)

參數1:當前是第幾頁,參數2:每頁顯示幾條記錄,參數3:是否要返回錯誤。

返回的分頁對象有三個屬性:items:獲得查詢的結果,pages:獲得一共有多少頁,page:獲得當前頁。

3.常用的邏輯符:

需要倒入包才能用的有:from sqlalchemy import * 

not_  and_  or_   還有上面說的排序desc。

常用的內建的有:in_      表示某個欄位在什麼範圍之中。

4.其他關係的一些資料庫查詢:

endswith():以什麼結尾。

startswith():以什麼開頭。

contains():包含

5.下面體會一下上面的這些用法:

1. 查詢所有使用者資料User.query.all()2. 查詢有多少個使用者User.query.count()3. 查詢第1個使用者User.query.first()4. 查詢id為4的使用者[3種方式]User.query.get(4)User.query.filter_by(id=4).first()    User.query.filter(User.id==4).first()filter:(類名.屬性名稱==)filter_by:(屬性名稱=)filter_by: 用於查詢簡單的列名,不支援比較子filter比filter_by的功能更強大,支援比較子,支援or_、in_等文法。5. 查詢名字結尾字元為g的所有資料[開始/包含]User.query.filter(User.name.endswith(‘g‘)).all()User.query.filter(User.name.contains(‘g‘)).all()6. 查詢名字不等於wang的所有資料[2種方式] from sqlalchemy import not_
注意了啊:邏輯查詢的格式:邏輯符_(類屬性其他的一些判斷)User.query.filter(not_(User.name==‘wang‘)).all()User.query.filter(User.name!=‘wang‘).all()7. 查詢名字和郵箱都以 li 開頭的所有資料[2種方式]from sqlalchemy import and_User.query.filter(and_(User.name.startswith(‘li‘), User.email.startswith(‘li‘))).all()User.query.filter(User.name.startswith(‘li‘), User.email.startswith(‘li‘)).all()8. 查詢password是 `123456` 或者 `email` 以 `itheima.com` 結尾的所有資料from sqlalchemy import or_User.query.filter(or_(User.password==‘123456‘, User.email.endswith(‘itheima.com‘))).all()9. 查詢id為 [1, 3, 5, 7, 9] 的使用者列表User.query.filter(User.id.in_([1, 3, 5, 7, 9])).all()10. 查詢name為liu的角色資料關係引用User.query.filter_by(name=‘liu‘).first().role.name11. 查詢所有使用者資料,並以郵箱排序排序User.query.order_by(‘email‘).all() 預設升序User.query.order_by(desc(‘email‘)).all() 降序12. 查詢第2頁的資料, 每頁只顯示3條資料help(User.query.paginate)三個參數: 1. 當前要查詢的頁數 2. 每頁的數量 3. 是否要返回錯誤pages = User.query.paginate(2, 3, False)pages.items # 擷取查詢的結果pages.pages # 總頁數pages.page # 當前頁數

 

python架構之Flask基礎篇(二)-------- 資料庫的操作

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.