1. 程式人生 > 其它 >flask操作資料庫

flask操作資料庫

flask操作資料庫

準備工作

  1. 安裝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

  1. 安裝pymysql
pip install pymysql
  1. 安裝flask-sqlalchemy
pip install flask-sqlalchemy
  1. 安裝flask-migrate,版本過高可能出現問題
pip install flask-migrate==2.7.0

配置資料庫

  1. 在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#除錯模式
  1. 在專案檔案下新建一個ext包,在包的init檔案內建立對映物件
# 建立一個對映物件
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()
  1. 建立完之後,需要將對映物件與app進行關聯,在apps包的init檔案內進行關聯
    # 將db(orm對映)物件和app進行關聯
    db.init_app(app)
  1. 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管理
  1. 在各藍圖中建立模型(類)時,要用到db的model
#在model.py檔案中
from exts import db
class User(db.Model):
  1. 模型的基礎建立格式和欄位型別
  1. 將建立好的模型(自定義的類)匯入到app.py檔案中
from apps.user.models import User
  1. 使用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()

查詢資料庫

  1. filter模糊查詢,返回名字結尾字元為g的所有資料。
User.query.filter(User.name.endswith('g')).all()

查詢結果為:列表裡套著物件
[<User 1>, <User 2>]
  1. 查詢:filter_by精確查詢
返回名字等於wang的所有user
User.query.filter_by(name='wang').all()

後面加.first()返回查詢到的第一個物件
all()返回查詢到的所有物件
  1. get(),引數為主鍵,如果主鍵不存在沒有返回內容
User.query.get(2)
  1. 邏輯非,返回名字不等於wang的所有資料
User.query.filter(User.name!='wang').all()
  1. 邏輯或,需要匯入or_
from sqlalchemy import or_
User.query.filter(or_(User.name!='wang',User.email.endswith('163.com'))).all()
  1. 邏輯與,需要匯入and,返回and()條件滿足的所有資料
from sqlalchemy import and_
User.query.filter(and_(User.name!='wang',User.email.endswith('163.com'))).all()
  1. not_ 相當於取反
from sqlalchemy import not_
User.query.filter(not_(User.name=='chen')).all()
  1. 其他
  1. 排序order_by
  1. limit限制

刪除資料

user = User.query.first()
db.session.delete(user)
db.session.commit()

更新資料

user = User.query.first()
user.name = 'dong'
db.session.commit()

模型表直接的關聯

  1. 一對多
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
  1. 多對多

需要定義一箇中間表,包含兩個模型的外來鍵欄位就可以了,並作為一個“複合主鍵”
在兩個需要做多對多的模型中隨便選擇一個模型,定義一個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

flask資料庫常見的資料型別和欄位