Flask模型類的關聯(一對多/多對多)和自關聯
在Flask中創建數據模型類,需要繼續自flask_sqlalchemy.SQLAchemy().models.Model
from flask_sqlalchemy import SQLAchemy db = SQLAchemy()
一對多
一對多模型的實現
一對多的模型類實現可以通過db.relationship(在一的一方)和db.ForeignKey(在多的一方).比如一個作者可以有多篇文章
class Author(db.Model): __tablename__ = 'info_author' id = db.Column(db.Integer,primary_key=True) name = db.Column(db.String(20), nullable=False) # 一的一方,relationship為Author 添加article屬性,Author_obj.article內容是以Author_obj.id == Article.author_id的一組Article對象 # backref(反向引用) 則為Article添加author屬性,Article_obj.author內容是以Article.author_id == Author_obj.id 的Author_obj article = db.relationship("Article",backref='author') class Article(db.Model): __tablename__ = "info_article" id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(20),nullable=False) # 多的一方,author_id 的取值范圍只能在info_author.id的范圍內 author_id = db.Column(db.Integer,db.ForeignKey('info_author.id'))
一對多和多對一的關聯查詢使用
在flask_sqlalchemy中,插入、修改、刪除操作,均由數據庫會話管理。
會話用 db.session 表示。在准備把數據寫入數據庫前,要先將數據添加到會話中然后調用 commit() 方法提交會話。
在 flask_sqlalchemy中,查詢操作是通過 query 對象操作數據。
最基本的查詢是返回表中所有數據,可以通過過濾器進行更精確的數據庫查詢。
數據庫遷移
from flask_migrate import Migrate, MigrateCommand from flask_script import Manager app = Flask(__name__) manager = Manager(app) # 腳本命令 migrate = Migrate(app,db) # 數據庫遷移綁定 manager.add_command('mysql',MigrateCommand) # 添加數據庫遷移的腳本命令
遷移三部曲:
- pyhton manage.py migrate_commandinit # 這里的migrate_command即是上面的‘mysql’
- python manage.py migrate_commandmigrate -m "database_migrate"
- python manage.py migrate_commandupgrade
查找一個作者的所有文章
Author.query.filter(Author.id==1).first().article.all() # 返回一個查詢集列表
查找某篇文章的作者
author = Article.query.filter(Article.title=='Python孫行者').first().author # 返回的是一個作者查詢集對象,可以author.name進行查詢具體的名字
多對多
多對多一般使用一張中間表和兩個一對多進而降低難度和更容易理解。下面以用戶收藏新聞為例,一個用戶可以收藏多條新聞,一條新聞可以被多個用戶收藏,那么這個就是一個多對多的關系。
我們可以通過一張用戶表(用戶id,姓名,用戶收藏的新聞的一個關聯屬性),一張新聞表(新聞id,新聞標題)以及一張中間表(用戶id,新聞i比如說,需要查找張三收藏了哪些新聞,那么我們就可以根據張三的用戶id到中間表查詢user_id為1的所有的news_id的數據,然后再回到新聞表,去根據news_id就可以查到對應的標題了。
代碼:
# 中間表 tb_user_collections = db.Table("info_user_collections", db.Cloumn("user_id", db.Integer, db.ForeignKey("info_user.id")), db.Cloumn("news_id", db.Integer, db.ForgignKey("info_news.id"))) # 用戶模型 class User(db.Model): __tablename__ = "info_user" id = db.Column(db.Integer, primary_key=True) # 用戶編號 name = db.Column(db.String(32), unique=True, nullable=False) # 用戶昵稱 collection_news = db.relationship("News", secondary=tb_user_collections, backref="user", lazy="dynamic") # 新聞模型 class News(db.Model): __tablename__ = "info_news" id = db.Column(db.Integer, primary_key=True) # 新聞id title = db.Column(db.String(32), nullable=False) # 新聞標題
class Comment(db.Model): """評論""" __tablename__ = "info_comment" id = db.Column(db.Integer, primary_key=True) # 評論編號 content = db.Column(db.Text, nullable=False) # 評論內容 parent_id = db.Column(db.Integer, db.ForeignKey("info_comment.id")) # 父評論id parent = db.relationship("Comment", remote_side=[id]) # 自關聯