Flask-SQLAlchemy簡單增刪改查,一對多,多對多


Flask-SQLAlchemy

  • flask用於orm操作表,一般使用flask- sqlalchemy .操作簡單,易於上手。

1.安裝

pip instal flask-sqlalchemy

2.配置信息

  • config.py
# 數據庫配置
DB_USERNAME = 'root'
DB_PASSWORD = 123
DB_HOST = '127.0.0.1'
DB_PORT = 3306
DB_NAME = 'sql_learn'
DB_URI = "mysql+pymysql://%s:%s@%s:%s/%s?charset=utf8" % (
    DB_USERNAME, DB_PASSWORD, DB_HOST, DB_PORT, DB_NAME
)
# 連接數據庫
SQLALCHEMY_DATABASE_URI= DB_URI
# 如果設置True,會消耗額外內存空間,它用於追蹤對象修改並發送信號
SQLALCHEMY_TRACK_MODIFICATIONS = False
# 調試設置為True
SQLALCHEMY_ECHO = True
  • 其他配置
SQLALCHEMY_POOL_TIMEOUT #連接超時時間
SQLALCHEMY_POOL_SIZE 數據庫池大小,default=5

3.表的創建

  • 實例化SQLAlchemy,在exts.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
  • model創建,models.py
from exts import db	#這里需要引入實例化的SQLAlchemy對象

"""
以下表關系:
一個用戶對應多篇文章(一對多)
一篇文章對應多個標簽,一個標簽對應多個文章(多對多)
"""
"""
一對一關系中,需要設置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外鍵關聯User表id. 這里ForeignKey一定要表名.id
    author_id = db.Column(db.Integer, db.ForeignKey('user.id'))
	# 這里不是字段,而是讓Article與User表創建關聯關系,backref是反向關聯關鍵字
    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))

  • 操作:
Tags表與Article通過第三張表建立多對多關系,通過Article表中tags字段(relationship方法),建立多對多關系:
secondary 多對多關聯類
cascade:設置級聯關系。 刪除可用delete,delete-orphan
single_parent:讓級聯關機支持多對多
passive_deletes :支持關聯(被動)刪除
# 則上面tags字段可以寫成:
tags = db.relationship("Tag", secondary=article_tag_table, backref='tags',cascade="delete, delete-orphan", single_parent=True, passive_deletes=True)
  • 常用表字段,及其意義
Integer	整型
String	字符串
Text	文本
DateTime 日期
Float  浮點型
Boolean  布爾值
PickleType  存儲一個序列化Pickle 后對象。 

4.數據庫遷移

  • 使用命令行形式遷移。在app.py
from flask import Flask
from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager
import config
from exts import db
# 實例化Flask對象
app = Flask(__name__)
# 配置信息加載
app.config.from_object(config)
# SQLAlchemy對象綁定app
db.init_app(app)
manager = Manager(app)
Migrate(app,db)
# 通過命令行形式遷移數據庫
manager.add_command("db",MigrateCommand)
if __name__ == '__main__':
    manager.run()
  • 數據庫手動創建庫。這里我命名的庫名sql_learn,在Terminal終端執行命令:
python3 manage.py db init #初始化migrate
python3 manage.py db migrate #生成遷移記錄
python3 manage.py db upgrade #提交更新至數據庫
  • 其他命令:
python manage.py db history  #查看歷史
python manage.py db downgrade 6af28765840d  #回退版本

5.單一的增刪改查

# 增加:
user = User(id=1,username="ming",email="123@163.com")
db.session.add(user)
db.session.commit()

# 修改數據 先執行查,再執行修改,相當於2條SQL語句
user = User.query.filter(User.username=="ming").first()
user.email = "abc@163.com"
db.session.commit()
# 修改方式1 只執行一條更新sql
db.session.query(User).filter_by(username="Limong").update({"email":"8888@163.com"})
# 修改方式2  只執行一條更新sql
User.query.filter(User.username == 'ming').update({'email': 'ABC@163.com'})
db.session.commit()
# 刪除方式
User.query.filter(User.username == "ming").delete()
db.session.commit()

# 查詢:
# 查詢所有:
result = User.query.all()
print(result)
# 根據主鍵查詢
result = User.query.get(1)
# 條件查
result = User.query.filter_by(username="ming").first()
# 多條件查詢
result = User.query.filter(and_(User.username=='name', User.email=='passwd')).all()
# 比較查詢
User.query.filter(User.id.__lt__(5)).all() # 小於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.id.in_([1,2,3,4,5])).all()
# 排序
result = User.query.order_by("id").all()
# 限制查詢   # 查詢id>2,並跳過前2條,總共查3條數據
result = User.query.filter(User.id.__gt__(2)).offset(2).limit(3)

6.一對多關系

  • 一對多關系創建表通過relationship關聯

6.1數據增加

  • 方式1:先查出對象,再添加
# 添加一個文章標題是:python基礎, 作者是xu
    create_obj = db.session.query(User).filter(User.username=="xu").first()
    article = Article(
        title="python基礎",
        author_id=create_obj.id,
        content = "python入門,變量,函數,面向對象..."
    )
    db.session.add(article)
    db.session.commit()
  • 方式2:通過relationship 添加數據
# 通過定義relationship
    # 1.在Article 表中添加數據,
    # 2.在User表中添加一條數據,並將User表中剛剛添加數據的id,添加到Article中,使其關聯起來
    create_obj = Article(
        title="python基礎2",
        content="python中生成器,迭代器...",
        author=User(username="wenfeng",email="123@163.com")
                         )
    db.session.add(create_obj)
    db.session.commit()
  • 方式3:relationship 反向添加數據
# 創建User對象
    create_obj = User(username = "sun",email="123@163.com")
    # 通過對象.backref定義名字,向Article添加2條數據。
    create_obj.articles = [
        Article(title="python進階1",content="內存管理機制"),
        Article(title="python進階2",content="垃圾回收機制")
    ]
    db.session.add(create_obj)
    db.session.commit()
  • 最后別忘了,關閉連接
db.session.close()

6.2數據查詢

  • 查詢所有數據
# 查詢所有文章,然后顯示文章名,文章內容,--->連表作者名,作者email
    article_list = db.session.query(Article).all()
    for row in article_list:
        print(row.title,row.content,row.author.username,row.author.email)
  • 反向查詢
user_list = db.session.query(User).all()
# 先查詢所有user.
    # 通過循環每一user對象, 再通過 backref 中的articles,反向查Article表中title
    for row in user_list:
        # print(row.__dict__)
        for row2 in row.articles:
            print(row.username,row2.title)

6.3.更新數據

  • 外鍵數據更新
# 查詢到作者對象
user_obj = db.session.query(User).filter(User.username == "xu").first()
# 查詢用戶對象id 與 Article外鍵id 關聯所有文章對象,並更新title 
db.session.query(Article).filter(Article.author_id == user_obj.id).update({"title":"vue基礎"})
db.session.commit()

6.4刪除數據

# 刪除 作者名為xu的文章
user_obj = db.session.query(User).filter(User.username=="xu").first()
db.session.query(Article).filter(Article.author_id == user_obj.id).delete()
db.session.commit()

7.多對多關系

  • 多對多關系,通過第三表將兩張表關聯起來

7.1基於relationship增加數據

# 通過 添加文章,再添加標簽
# 首先新建Article對象,
article_obj = Article(title="Go基礎",content="go語言指針。。。")
# 添加標簽對象。tags為Article表中backref用於關聯Tag表多對多關系
article_obj.tags = [Tag(name="編譯型語言"),Tag(name="支持協程"),Tag(name="非常快")]
db.session.add(article_obj)
# 提交數據
db.session.commit()
# 關閉連接
db.session.close()

7.2基於relationship查詢數據

  • 正向查
# 查詢所有書籍和其標簽
article_obj = db.session.query(Article).all()
# 遍歷循環文章
for row in article_obj:
	# 遍歷循環每個文章tag:
	for row2 in row.tags:
		# 打印title,name
		print(row.title,row2.name)
  • 反向查
# 通過tag標簽查詢所有文章
# 查詢所有tag標簽
tag_obj = db.session.query(Tag).all()
# 遍歷循環標簽
for row in tag_obj:
    # 通過每個標簽對象.tags (注意此時tags為Article中字段名)
    #(此字段通過relationship,關聯Tag表)
    for row2 in row.tags:
        # 打印tag的名字和文章title
        print(row.name,row2.title)

7.3刪除數據

  • 單一刪除
# 查詢 title為Go基礎的對象
article_obj = Article.query.filter(Article.title =="Go基礎").first()
# 查詢 tag為非常快的對象
tag = Tag.query.filter(Tag.name == "非常快").first()
# 通過文章對象.tags (tags通過relationship與Tag表建立關系)
article_obj.tags.remove(tag)
db.session.commit()
  • 級聯刪除
# 級聯刪除
# 查詢到 title為 Go基礎 文章
article_obj = Article.query.filter(Article.title =="Go基礎").first()
# 連表查詢到所關聯所有tags
tags = Tag.query.join(article_tag_table).join(Article).filter(Article.title =="Go基礎").all()
for t in tags:
    # 遍歷循環tag標簽,逐個刪除 title為Go基礎   的對象
    article_obj.tags.remove(t)
    #最后刪除 title為 Go基礎 文章對象
    db.session.delete(article_obj)
    db.session.commit()
    # 關閉連接
    db.session.close()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM