Flask與數據庫:SQLAlchemy模型定義

在Web開發中,數據庫是存儲和管理數據的核心。Flask本身不內置數據庫操作功能,但藉助擴展庫SQLAlchemy可以輕鬆實現與數據庫的交互。SQLAlchemy是一個強大的ORM(對象關係映射)工具,它允許我們通過Python對象直接操作數據庫,無需編寫複雜的SQL語句。

一、安裝必要的庫

首先需要安裝Flask和Flask-SQLAlchemy(Flask的SQLAlchemy擴展)。如果使用SQLite數據庫(適合開發環境),無需額外安裝驅動;若使用MySQL或PostgreSQL,需安裝對應驅動(如pymysqlpsycopg2)。

pip install flask flask-sqlalchemy

二、初始化Flask應用與SQLAlchemy

在項目中創建app.py,首先導入必要的庫並初始化Flask應用和SQLAlchemy:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

# 初始化Flask應用
app = Flask(__name__)

# 配置數據庫連接URI(這裏使用SQLite,文件名爲mydatabase.db)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db'
# 關閉SQLAlchemy的修改跟蹤(減少性能開銷)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 初始化SQLAlchemy實例,綁定到Flask應用
db = SQLAlchemy(app)

三、定義第一個模型

模型本質是Python類,繼承自db.Model,類屬性對應數據庫表的字段。以下是一個簡單的User模型示例:

class User(db.Model):
    # 1. 主鍵字段(自增整數)
    id = db.Column(db.Integer, primary_key=True)

    # 2. 普通字段:字符串類型,長度50,不可爲空,唯一
    username = db.Column(db.String(50), nullable=False, unique=True)

    # 3. 字符串類型,長度120,唯一,不可爲空
    email = db.Column(db.String(120), unique=True, nullable=False)

    # 4. 整數類型,允許爲空
    age = db.Column(db.Integer)

    # 5. 文本類型,存儲長文本
    bio = db.Column(db.Text)

    # __repr__方法:對象打印時顯示友好信息
    def __repr__(self):
        return f'<User {self.username}>'

模型字段類型與參數說明

字段類型 說明 常用參數
db.Integer 整數類型 primary_key=True(主鍵)
db.String(n) 字符串類型,n爲最大長度 nullable=False(不可爲空)
db.Text 長文本類型 default(默認值)
db.Boolean 布爾類型 default=False
db.DateTime 日期時間類型 default=datetime.utcnow

關鍵參數
- primary_key=True:設爲主鍵,唯一且自增
- unique=True:字段值唯一(如用戶名、郵箱)
- nullable=False:字段不可爲空(必填)
- default:設置默認值(如default=0表示默認年齡爲0)

四、定義帶關係的模型

實際開發中,數據往往存在關聯。以“用戶-文章”爲例,一個用戶可以發佈多篇文章(一對多關係):

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    content = db.Column(db.Text, nullable=False)

    # 外鍵:關聯到User表的id字段(User表名默認小寫)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

    # 定義關係:User模型通過posts屬性反向關聯到Post
    author = db.relationship('User', backref=db.backref('posts', lazy=True))

    def __repr__(self):
        return f'<Post {self.title}>'

關係說明
- db.ForeignKey('user.id'):外鍵約束,確保user_id必須是User表中已存在的id
- relationship('User', backref=...):定義User和Post的雙向關係,backref讓User自動擁有posts屬性(如user.posts可獲取該用戶的所有文章)

五、創建數據庫表

定義好模型後,需要將模型映射到數據庫表。通過db.create_all()方法自動創建表(需在應用上下文中執行):

# 在應用上下文中創建表
with app.app_context():
    db.create_all()  # 生成所有模型對應的表

注意:若模型有修改(如新增字段),需重新執行db.create_all(),但SQLAlchemy會自動處理表結構更新(不會刪除已有數據)。

六、使用模型進行數據操作

模型定義完成後,即可通過Python對象操作數據庫(CRUD:增刪改查)。以下是常見操作示例:

1. 創建記錄(新增數據)

# 創建用戶
new_user = User(
    username="張三",
    email="zhangsan@example.com",
    age=25,
    bio="熱愛編程的初學者"
)

# 添加到數據庫會話並提交
db.session.add(new_user)
db.session.commit()

2. 查詢記錄

# 查詢所有用戶
all_users = User.query.all()
print(all_users)  # 輸出:[<User 張三>, ...]

# 按條件查詢(如查用戶名是“張三”的用戶)
user = User.query.filter_by(username="張三").first()
print(user.age)  # 輸出:25

# 關聯查詢(獲取用戶的所有文章)
user = User.query.get(1)  # 獲取id=1的用戶
posts = user.posts  # 通過posts屬性獲取該用戶的文章列表

3. 更新記錄

user = User.query.filter_by(username="張三").first()
user.age = 26  # 修改年齡
db.session.commit()  # 提交修改

4. 刪除記錄

user = User.query.filter_by(username="張三").first()
db.session.delete(user)  # 標記刪除
db.session.commit()  # 執行刪除

七、總結

SQLAlchemy模型定義是Flask與數據庫交互的基礎。通過定義繼承db.Model的Python類,我們可以:
- 用類屬性映射數據庫表字段
- 通過db.Column設置字段類型和約束
- 用relationship定義表間關係
- 通過db.create_all()自動創建表結構

掌握模型定義後,即可輕鬆實現數據的增刪改查,無需直接編寫SQL語句。後續可進一步學習更復雜的表關係(如多對多)和高級查詢技巧。

提示:開發時可使用flask shell快速測試模型操作,執行flask shell後在Python環境中導入模型並操作。

小夜