flask sqlalchemy
pip install flask-sqlalchemy
pip install flask-mysqldb
pip install pymysql
flask-sqlalchemy所作的操作只是把模型類轉換為sql語句,然後通過資料庫驅動訪問mysql,在獲取到結果後再把資料轉換為模型物件
Flask的資料庫設定:
app.config[‘SQLALCHEMY_DATABASE_URI’] = ‘mysql://root:[email protected]:3306/test’
設定每次請求結束後會自動提交資料中的更改,官方不推薦設定
app.config[‘SQLALCHEMY_COMMIT_ON_TEARDOWN’] = True
#如果一旦在資料庫中把表結構修改,那麼在sqlalchemy中的模型類也進行修改
app.config[‘SQLALCHEMY_TRACK_MODIFICATIONS’] = True
查詢時顯示原始SQL語句
app.config[‘SQLALCHEMY_ECHO’] = True
db = SQLAlchemy(app)
建立daemo_db.py內容如下
# coding:utf-8 from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) class Config(object): SQLALCHEMY_DATABASE_URI = "mysql://root:[email protected]:3306/db_python04" # 設定sqlalchemy自動跟蹤資料庫 SQLALCHEMY_TRACK_MODIFICATIONS = True app.config.from_object(Config) # 表名的常見規範,並不是以資料庫模型名稱命名 # ihome -> ih_user資料庫名縮寫_表名 # tbl_usertbl_表名 # 建立資料庫sqlalchemy工具物件 db = SQLAlchemy(app) # 建立資料庫模型類 class Role(db.Model): __tablename__ = "tbl_roles" # 資料庫中真實存在的欄位, db.Column id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True) # 資料庫中不真實存在的,比如模型與模型之間的一種關聯,根據角色查詢屬於這個角色的使用者有哪些 # 這裡的設計不像外來鍵是根據表的實際情況考慮,而根據模型考慮的 # User 是讓role物件可以獲得user中的屬性 # backref="role"可以讓user物件有個role屬性獲得role中的資訊,這個不是必須新增的,如果不新增那麼user物件要通過外來鍵role_id獲得這個使用者的角色資訊 users = db.relationship("User", backref="role") class User(db.Model): __tablename__ = "tbl_users" id = db.Column(db.Integer, primary_key=True)# 整型的主鍵,會預設設定為自增主鍵 name = db.Column(db.String(64), unique=True) email = db.Column(db.String(126), unique=True) password = db.Column(db.String(128)) role_id = db.Column(db.Integer, db.ForeignKey("tbl_roles.id"))# 外來鍵 # @app.route('/') # def index(): if __name__ == '__main__': # app.run() # 清除資料庫的所有資料 db.drop_all() # 建立表 db.create_all() # 新增資料 # 建立物件 role1 = Role(name="admin") # 用session記錄物件任務 db.session.add(role1) # 提交任務到資料庫中 db.session.commit() role2 = Role(name="stuff") db.session.add(role2) db.session.commit() us1 = User(name='zhangsan', email='[email protected]', password='123', role_id=role1.id) us2 = User(name='lisi', email='[email protected]', password='123', role_id=role2.id) us3 = User(name='wangwu', email='[email protected]', password='123', role_id=role2.id) us4 = User(name='zhaoliu', email='[email protected]', password='123', role_id=role1.id) # 一次儲存多條資料 db.session.add_all([us1, us2, us3, us4]) db.session.commit()
在pycharm中通過終端進入虛擬環境
進入python,並匯入daemon_db
# 使用db.session查詢指定物件的所有記錄
# 這是sqlalchemy提供的最底層的方法
db.session.query(Role).all()
db.session.query(Role).first()
是flask-sqlalchemy查詢
# 查詢Role物件的所有資料,結果是一個列表
# 這是flask-sqlalchemy封裝sqlalchemy後的方法
li = Role.query.all()
# 獲得一個role型別的物件
r = li[0]
# 獲得物件的一個屬性值
r.name
>>> li = Role.query.all() >>> r = li[0] >>> r <Role 1> >>> r.name 'admin' >>>
# 查詢第一條記錄
>>> r = Role.query.first() >>> r.name 'admin' >>>
# 獲取一個具體物件,必須接受一個引數,必須是主鍵的值
>>> r = Role.query.get(2) >>> r.name 'stuff'
# 常用的sqlalchemy查詢過濾器
過濾器 說明
filter() 把過濾器加到原查詢上,返回一個新查詢
filter_by() 把等值過濾加到原查詢上,返回一個新查詢
limit 使用知道的值限定原查詢返回的結果
offset() 偏移原查詢返回的結果,返回一個新查詢
order_by() 根據指定條件對原查詢結果進行排序,返回一個新查詢
group_by() 根據指定條件對原查詢結果進行分組,返回一個新查詢
# 只針對user表進行查詢,那麼user的欄位就可以進行簡寫操作
# 返回一個查詢,如果要獲得結果還需要在結尾加 all() 或first()
# 只針對user表進行查詢,那麼user的欄位就可以進行簡寫操作
# 返回一個查詢,如果要獲得結果還需要在結尾加 all() 或first()
# 完整查詢語法
User.query.filter().order_by().offset().limit().all()
>>> u1 = User.query.filter_by(name='zhangsan').all() >>> u1 [<User 1>] >>> u1[0].name 'zhangsan' >>> u1[0].email '[email protected]' >>> u2 = User.query.filter_by(name='zhangsan').first() >>> u2.name 'zhangsan' >>> u2.id 1 >>> u2.email '[email protected]'
# 查詢條件兩個,以 and 的方式拼接,並且匹配方式必須是完全匹配 =,不能使用模糊查詢,filter_by是filter的簡寫形式
>>> u1 = User.query.filter_by(name='zhangsan', role_id=1).all() >>> u1[0] <User 1>
#filter是萬能過濾器,但是即使只差一張表,欄位名都要加上物件名稱
>>> user = User.query.filter(User.name=='zhangsan', User.role_id==1).all() >>> user[0].name 'zhangsan'
# 執行或操作
# 查詢名字為zhangsan 或郵箱以 163.com 結尾,返回一個列表
>>> from sqlalchemy import or_ >>> li = User.query.filter(or_(User.name=='zhangsan',User.email.endswith("163.com"))).all() >>> li[0].name 'zhangsan' >>> li[1].name 'lisi'
#(跳過兩條記錄)從第3條記錄開始取
>>> li=User.query.offset(2).all() >>> li[0].name 'wangwu' >>> li[1].name 'zhaoliu'
#(跳過1條,取兩條)
>>> User.query.offset(1).limit(2).all() [<User 2>, <User 3>]
# 根據id反向排序,不推薦
>>> User.query.order_by("-id").all() C:\Users\Administrator\.virtualenvs\flask-0VgPQDMY\lib\site-packages\sqlalchemy\sql\compiler.py:763: SAWarning: Can't resolve label reference '-id'; converting to text() (this warning may be suppressed after 10 oc currences) util.ellipses_string(element.element), [<User 4>, <User 3>, <User 2>, <User 1>]
# 根據id反向排序,官方推薦
>>> User.query.order_by(User.id.desc()).all() [<User 4>, <User 3>, <User 2>, <User 1>]
#group_by語句不能用flask-sqlalchemy的物件進行操作,必須用sqlalchemy最原始的方式進行操作,並要衝sqlalchemy中匯入func這個工具
#進行分組查詢,query中必須包含分組後必須顯示出的欄位
>>> from sqlalchemy import func >>> db.session.query(User.role_id,func.count(User.role_id)).group_by(User.role_id).all() [(1, 2), (2, 2)]
# 對應 的sql語句
select role_id,count(role_id) from tbl_users group by role_id;
##############
更新操作
# 先獲取物件
# 修改物件屬性
# 將物件修改後更新到資料庫
>>> user = User.query.get(1) >>> user.name = "python" >>> db.session.add(user) >>> db.session.commit() >>> User.query.get(1) >>> u1=User.query.get(1) >>> u1.name 'python'
# 查詢出結果過直接更新
>>> User.query.filter_by(name="wangwu").update({"name":"linux","email":"[email protected]"}) 1 >>> db.session.commit()
#刪除操作
>>> user = User.query.get(3) >>> db.session.delete(user) >>> db.session.commit() >>> User.query.all() [<User 1>, <User 2>, <User 4>]