flask操作資料庫
阿新 • • 發佈:2022-12-10
flask操作資料庫
準備工作
- 安裝flask-script(版本過高可能會報錯)
pip install flask-script==2.0.3
使用flask-script裡的Manager類例項化來管理專案的啟動等
from apps import create_app
from flask_script import Manager
app = create_app()
manager = Manager(app=app)
if __name__ == '__main__':
# 執行app模組
manager.run()
在啟動專案時由原來的python app.py 改成了python app.py runserver
- 安裝pymysql
pip install pymysql
- 安裝flask-sqlalchemy
pip install flask-sqlalchemy
- 安裝flask-migrate,版本過高可能出現問題
pip install flask-migrate==2.7.0
配置資料庫
- 在settings裡配置一下資料庫連線路徑
class DevelopmentConfig: ENV = 'development' # 設定環境為開發環境 DEBUG = True # 設定debug為true SQLALCHEMY_DATABASE_URI='mysql+pymysql://root:[email protected]:3306/flaskday05'#訪問的資料庫+用的驅動://資料庫的使用者名稱:密碼@伺服器地址:埠號/資料庫 # 設定sqlalchemy不自動更跟蹤資料庫 SQLALCHEMY_TRACK_MODIFICATIONS=False SQLALCHEMY_ECHO=True#除錯模式
- 在專案檔案下新建一個ext包,在包的init檔案內建立對映物件
# 建立一個對映物件
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
- 建立完之後,需要將對映物件與app進行關聯,在apps包的init檔案內進行關聯
# 將db(orm對映)物件和app進行關聯
db.init_app(app)
- flask-migrate是一個為Flask應用處理SQLAlchemy資料庫遷移的擴充套件,使得可以通過Flask的命令列介面或者Flask-Scripts對資料庫進行操作。
#在app.py檔案中,當建立完app物件之後 from flask_migrate import Migrate, MigrateCommand migrate=Migrate(app=app,db=db)#建立app影響資料庫的對映 manager.add_command('db',MigrateCommand)#將命令交給manager管理
- 在各藍圖中建立模型(類)時,要用到db的model
#在model.py檔案中
from exts import db
class User(db.Model):
- 模型的基礎建立格式和欄位型別
- 將建立好的模型(自定義的類)匯入到app.py檔案中
from apps.user.models import User
- 使用terminal執行flask專案
初始化(一個專案只需要初始化一次,用來生成migrations資料夾)python app.py db init
更新版本(每次修改後要執行,用來在versions檔案中生成最新的版本py檔案)python app.py db migrate
資料庫同步(每次修改要執行,用來將最新版本的內容更新到資料庫上)python app.py db upgrade
刪除時:python app.py db downgrate 降級並刪除版本檔案
往資料庫插入資料
每次插入單挑資料
一次性插入多條資料
# 一次性插入多條資料
user1 = User(name='wang',email='[email protected]',pswd='123456',role_id=role1.id)
user2 = User(name='zhang',email='[email protected]',pswd='201512',role_id=role2.id)
user3 = User(name='chen',email='[email protected]',pswd='987654',role_id=role2.id)
user4 = User(name='zhou',email='[email protected]',pswd='456789',role_id=role1.id)
db.session.add_all([user1,user2,user3,user4])
db.session.commit()
查詢資料庫
- filter模糊查詢,返回名字結尾字元為g的所有資料。
User.query.filter(User.name.endswith('g')).all()
查詢結果為:列表裡套著物件
[<User 1>, <User 2>]
- 查詢:filter_by精確查詢
返回名字等於wang的所有user
User.query.filter_by(name='wang').all()
後面加.first()返回查詢到的第一個物件
all()返回查詢到的所有物件
- get(),引數為主鍵,如果主鍵不存在沒有返回內容
User.query.get(2)
- 邏輯非,返回名字不等於wang的所有資料
User.query.filter(User.name!='wang').all()
- 邏輯或,需要匯入or_
from sqlalchemy import or_
User.query.filter(or_(User.name!='wang',User.email.endswith('163.com'))).all()
- 邏輯與,需要匯入and,返回and()條件滿足的所有資料
from sqlalchemy import and_
User.query.filter(and_(User.name!='wang',User.email.endswith('163.com'))).all()
- not_ 相當於取反
from sqlalchemy import not_
User.query.filter(not_(User.name=='chen')).all()
- 其他
- 排序order_by
- limit限制
刪除資料
user = User.query.first()
db.session.delete(user)
db.session.commit()
更新資料
user = User.query.first()
user.name = 'dong'
db.session.commit()
模型表直接的關聯
- 一對多
class Role(db.Model):
...
#關鍵程式碼
user = db.relationship('User', backref='role', lazy='dynamic')
...
class User(db.Model):
...
role = db.Column(db.Integer, db.ForeignKey('roles.id'))
- 其中realtionship描述了Role和User的關係。在此文中,第一個引數為對應參照的類"User"
- 第二個引數backref表示當使用user物件反向查詢時,使用user.role查詢到role表中的資料
- 第三個引數lazy決定了什麼時候SQLALchemy從資料庫中載入外來鍵模型資料
如果設定為子查詢方式(subquery),則會在載入完Role物件後,就立即載入與其關聯的物件,這樣會讓總查詢數量減少,但如果返回的條目數量很多,就會比較慢
設定為 subquery 的話,role.users 返回所有資料列表
另外,也可以設定為動態方式(dynamic),這樣關聯物件會在被使用的時候再進行載入,並且在返回前進行過濾,如果返回的物件數很多,或者未來會變得很多,那最好採用這種方式
設定為 dynamic 的話,role.users 返回查詢物件,並沒有做真正的查詢,可以利用查詢物件做其他邏輯,比如:先排序再返回結果
關聯查詢
角色和使用者的關係是一對多的關係,一個角色可以有多個使用者,一個使用者只能屬於一個角色。
- 查詢角色的所有使用者
#查詢roles表id為1的角色
ro1 = Role.query.get(1)
#查詢該角色的所有使用者
ro1.use.all()
- 查詢使用者所屬角色
#查詢users表id為3的使用者
us1 = User.query.get(3)
#查詢使用者屬於什麼角色
us1.role
- 多對多
需要定義一箇中間表,包含兩個模型的外來鍵欄位就可以了,並作為一個“複合主鍵”
在兩個需要做多對多的模型中隨便選擇一個模型,定義一個relationship屬性,來繫結三者之間的關係,在使用relationship的時候,需要傳入一個secondary=中間表模型名。
# 中間表,也可以重新定義一個類class,表示中間表
article_tag = db.Table(
'article_tag',
db.Column('article_id', db.Integer,db.ForeignKey("article.id"),primary_key=True),
db.Column('tag_id', db.Integer, db.ForeignKey("tag.id"), primary_key=True)
)
# 文章表
class Article(db.Model):
__tablename__ = 'article'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(64))
tags = db.relationship('Tag', secondary=article_tag, backref=db.backref('articles'))
# 這裡需要指定一個引數secondary,值為中間表的表名
# 標籤表
class Tag(db.Model):
__tablename__ = 'tag'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(32))
多對多關係的查詢
1.查詢文章所有的標籤:
article = Article.query.filter(Article.title=="xxx").first()
tags = article.tags
2.查詢一個標籤涉及的所有文章:
tag = Tag.query.get(2)
articles = tag.articles