洛谷P5662 紀念品 題解 完全揹包
阿新 • • 發佈:2020-09-09
Flask-SQLAlchemy詳解
flask中一般使用flask-sqlalchemy來操作資料庫,使用起來比較簡單,易於操作。
安裝
pip install flask-sqlalchemy
配置
配置選項 | 說明 |
---|---|
SQLALCHEMY_DATABASE_URI |
連線資料庫。示例:mysql://username:password@host/post/db?charset=utf-8 |
SQLALCHEMY_BINDS |
一個將會繫結多種資料庫的字典。 更多詳細資訊請看官文繫結多種資料庫. |
SQLALCHEMY_ECHO |
除錯設定為true |
SQLALCHEMY_POOL_SIZE |
資料庫池的大小,預設值為5。 |
SQLALCHEMY_POOL_TIMEOUT |
連線超時時間 |
SQLALCHEMY_POOL_RECYCLE |
自動回收連線的秒數。 |
SQLALCHEMY_MAX_OVERFLOW |
控制在連線池達到最大值後可以建立的連線數。當這些額外的 連接回收到連線池後將會被斷開和拋棄。 |
SQLALCHEMY_TRACK_MODIFICATIONS |
如果設定成 True (預設情況),Flask-SQLAlchemy 將會追蹤物件的修改並且傳送訊號。這需要額外的記憶體, 如果不必要的可以禁用它。 |
操作資料庫需要先建立一個db物件,通常寫在exts.py
檔案裡。
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
flask專案一般將資料庫配置寫入configs.py
檔案裡面,配置在建立引擎前需寫好,不要在程式執行時修改配置,如下。
HOST = '127.0.0.1'
PORT = '3306'
DATABASE = 'flask1'
USERNAME = 'root'
PASSWORD = '123456'
DB_URI = "mysql+pymysql://{username}:{password}@{host}:{port}/{db}?charset=utf8".format(username=USERNAME,password=PASSWORD, host=HOST,port=PORT, db=DATABASE)
SQLALCHEMY_DATABASE_URI = DB_URI
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_ECHO = True
寫完資料庫配置後需要和app繫結,app.py
檔案裡寫flask應用的建立和藍圖的註冊等等,如下:
from flask import Flask
import configs
from exts import db
app = Flask(__name__)
# 載入配置檔案
app.config.from_object(configs)
# db繫結app
db.init_app(app)
模型
資料型別 | 說明 |
---|---|
Integer | 整型 |
String | 字串 |
Text | 文字 |
DateTime | 日期 |
Float | 浮點型 |
Boolean | 布林值 |
PickleType | 儲存一個序列化( Pickle )後的Python物件 |
LargeBinary | 巨長度二進位制資料 |
1.表的建立
# 建表寫在models.py檔案裡面
from ext import db
"""
以下表關係:
一個使用者對應多篇文章(一對多)
一篇文章對應多個標籤,一個標籤對應多個文章(多對多)
"""
"""
一對一關係中,需要設定relationship中的uselist=Flase,其他資料庫操作一樣。
一對多關係中,外來鍵設定在多的一方中,關係(relationship)可設定在任意一方。
多對多關係中,需建立關係表,設定 secondary=關係表
"""
# 使用者表
class User(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(50))
email = db.Column(db.String(50))
# 關係表(多對多)
article_tag_table = 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, autoincrement=True)
title = db.Column(db.String(100))
content = db.Column(db.Text)
author_id = db.Column(db.Integer, db.ForeignKey('user.id'))
author = db.relationship("User", backref="articles")
tags = db.relationship("Tag", secondary=article_tag_table, backref='tags')
# 標籤表
class Tag(db.Model):
__tablename__ = 'tag'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(50))
2.表的對映
建立好表後需要對映到資料庫中,這裡需要用到flask-migrate
庫。下面是啟動檔案manage.py
。
from flask_script import Manager, Server
from app import app
from flask_migrate import Migrate, MigrateCommand
from ext import db
from first import models # 模型檔案必須匯入進來,否則執行報錯
manager = Manager(app)
Migrate(app=app, db=db)
manager.add_command('db', MigrateCommand) # 建立資料庫對映命令
manager.add_command('start', Server(port=8000, use_debugger=True)) # 建立啟動命令
if __name__ == '__main__':
manager.run()
配置好啟動檔案後,進入專案根目錄,在命令列輸入以下程式碼:
>python manage.py db init
>python manage.py db migrate
>python manage.py db upgrade
3.表的增刪查改
# 原生sql語句操作
sql = 'select * from user'
result = db.session.execute(sql)
# 查詢全部
User.query.all()
# 主鍵查詢
User.query.get(1)
# 條件查詢
User.query.filter_by(User.username='name')
# 多條件查詢
from sqlalchemy import and_
User.query.filter_by(and_(User.username =='name',User.password=='passwd'))
# 比較查詢
User.query.filter(User.id.__lt__(5)) # 小於5
User.query.filter(User.id.__le__(5)) # 小於等於5
User.query.filter(User.id.__gt__(5)) # 大於5
User.query.filter(User.id.__ge__(5)) # 大於等於5
# in查詢
User.query.filter(User.username.in_('A','B','C','D'))
# 排序
User.query.order_by('age') # 按年齡排序,預設升序,在前面加-號為降序'-age'
# 限制查詢
User.query.filter(age=18).offset(2).limit(3) # 跳過二條開始查詢,限制輸出3條
# 增加
use = User(id,username,password)
db.session.add(use)
db.session.commit()
# 刪除
User.query.filter_by(User.username='name').delete()
# 修改
User.query.filter_by(User.username='name').update({'password':'newdata'})