1. 程式人生 > 實用技巧 >洛谷P5662 紀念品 題解 完全揹包

洛谷P5662 紀念品 題解 完全揹包

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'})