1. 程式人生 > 資料庫 >資料庫關聯查詢與模型之間的關聯

資料庫關聯查詢與模型之間的關聯

關聯查詢(常用的SQLAlchemy關係選項)

 

 

from flask import Flask,jsonify,render_template
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)

class Config():
    # DEBUG除錯模式
    DEBUG = True
    # json多位元組轉unicode編碼
    JSON_AS_ASCII = False
    # 資料庫連結配置
    # SQLALCHEMY_DATABASE_URI = "mysql://賬號:密碼@IP/資料庫名?編碼"
    SQLALCHEMY_DATABASE_URI = "mysql://root:[email protected]:3306/students?charset=utf8mb4"
    # 動態追蹤修改設定,如未設定只會提示警告
    SQLALCHEMY_TRACK_MODIFICATIONS = True
    # 查詢時會顯示原始SQL語句
    SQLALCHEMY_ECHO = True

app.config.from_object(Config)
db = SQLAlchemy()
db.init_app(app)

"""建立模型類"""
class Student(db.Model):
    __tablename__ = "tb_student"
    id = db.Column(db.Integer, primary_key=True,comment="主鍵ID")
    name = db.Column(db.String(250), comment="姓名")
    age = db.Column(db.Integer, comment="年齡")
    sex = db.Column(db.Boolean, default=False, comment="性別")
    money = db.Column(db.DECIMAL(8,2), nullable=True, comment="錢包")

    def __repr__(self):
        return self.name

class Teacher(db.Model):
    __tablename__ = "tb_teacher"
    id = db.Column(db.Integer, primary_key=True, comment="主鍵ID")
    name = db.Column(db.String(250), comment="姓名")
    sex = db.Column(db.Boolean, default=False, comment="性別")
    option = db.Column(db.Enum("講師","助教","班主任"), default="講師", comment="教職")

    def __repr__(self):
        return self.name

class Course(db.Model):
    __tablename__ = "tb_course"
    id = db.Column(db.Integer, primary_key=True, comment="主鍵ID")
    name = db.Column(db.String(250), unique=True, comment="課程名稱")
    price = db.Column(db.Numeric(6, 2))

    def __repr__(self):
        return self.name

@app.route("/")
def index():
    """資料庫進階操作"""
    """filter設定判斷條件
    ==  判斷相等
    >=
    <
    >
    <=
    !=
    """
    # student = Student.query.filter(Student.name=="xiaohui32號").first()
    # if student is None:
    #     return jsonify({"error":"100404","errmsg":"沒有該學生資訊!"})
    # print(student)
    """filter設定模糊查詢"""
    # like模糊條件(最好只用於少量資料)
    # 模型.欄位.like("%值%")  等價於  模型.欄位.contains("值")    包含xxx
    # 模型.欄位.like("值%")   等價於  模型.欄位.startswith("值")  以xxx開頭
    # 模型.欄位.like("%值")   等價於  模型.欄位.endswith("值")    以xxx結尾
    # 模型.欄位.like("__")    值長度為2個字元的.幾個下劃線代表幾個字元

    # student_list = Student.query.filter(Student.name.like("%xiaohui%")).all()
    # student_list = Student.query.filter(Student.name.startswith("xiao")).all()
    # student_list = Student.query.filter(Student.name.like("________")).all()

    """filter_by設定精確條件查詢資料"""
    # filter_by 只支援一個等號作為判斷條件,而且欄位左邊不需要宣告模型類名
    # 可以用於獲取一條資料,也可以獲取多條資料
    # student = Student.query.filter_by(money=1000).first()
    # print(student)

    """filter多條件查詢"""
    # 多條件需要基於邏輯運算來編寫,當然,可以其他的宣告方式
    """and_ 並且, 與"""
    # from sqlalchemy import and_
    # # 方式1:
    # student_list1 = Student.query.filter(Student.money==1000,Student.sex==True).all()
    # # 方式2:
    # student_list2 = Student.query.filter(and_(Student.money==1000,Student.sex==True)).all()
    #
    # print(student_list1, student_list2)

    """or_ 或者,或"""
    # from sqlalchemy import or_
    # student_list = Student.query.filter( or_(Student.age > 17, Student.age < 15) ).all()
    # print(student_list)

    """not_ 排除,非"""
    from sqlalchemy import not_
    # student_list = Student.query.filter(not_(Student.age > 17)).all()
    # print(student_list)

    """filter值範圍查詢"""
    # 查詢年齡=15或者17或者19的
    # student_list = Student.query.filter(Student.age.in_([15,17,19])).all()
    # print(student_list)

    """order_by結果排序"""
    # order_by(模型.欄位.desc())   db.desc(模型.欄位)    倒序
    # order_by(模型.欄位.asc())    db.asc(模型.欄位)     升序
    # student_list = Student.query.order_by(db.desc(Student.money)).all()
    # student_list = Student.query.order_by(Student.money.desc()).all()
    # print(student_list)

    """count 統計結果數量"""
    # ret = Student.query.filter(Student.age>17).count()
    # print(ret)

    """limit 結果數量進行限制"""
    """offse 對查詢開始位置進行設定"""
    # 對學生的錢包進行從大到小排名,第3-第5名的學生
    # student_list = Student.query.order_by(Student.money.desc()).offset(2).limit(3).all() #offset從下標2開始取(limit)三個
    # print(student_list)

    """paginate分頁器"""
    # paginate(page=當前頁碼, per_page=每一頁資料量, max_per_page=每一頁最大資料量)
    # 當前頁碼,預設是從request.args["page"],如果當前引數沒有值,則預設為1
    # 每一頁資料量,預設是100條
    # 因為分頁器有提供了一個  request.args.["per_page"]給客戶端設定每一頁資料量,所以再次限定客戶端最多能設定的每一頁資料量
    pagination = Student.query.filter(Student.sex==True).paginate(per_page=1)
    print(pagination)
    return render_template("list.html",pagination=pagination)
    # print( pagination.items ) # 獲取當前頁資料量
    # print( pagination.has_next ) # 如果還有下一頁資料,則結果為True
    # print( pagination.has_prev ) # 如果有上一頁資料,則結果為True
    # print( pagination.page ) # 當前頁頁碼 request.args.get("page",1)
    # print( pagination.total ) # 本次查詢結果的資料總量[被分頁的資料量總數]
    # print( pagination.pages )   # 總頁碼
    # print( pagination.prev() ) # 上一頁的分頁器物件,如果沒有上一頁,則預設為None
    # print( pagination.next() ) # 下一頁的分頁器物件,如果沒有下一頁,則預設為None
    # if pagination.has_next:
    #     print( pagination.next().items ) # 下一頁的資料列表

    return "Ok"

if __name__ == '__main__':
    # with app.app_context():
    #     db.create_all() # 根據模型建立所有的資料表
    #     # db.drop_all()   # 刪除模型對應的所有資料表
    app.run()
關聯查詢

 

模型之間的關聯

一對一

class Student(db.Model):
    """個人資訊主表"""
    ....
    # 關聯屬性,這個不會被視作表字段,只是模型的屬性。
    # 因為StudentInfo和Student是一對一的關係,所以uselist=False表示關聯一個數據
    info = db.relationship("StudentInfo",uselist=False,backref="own")


class StudentInfo(db.Model):
    """個人資訊附加表"""

    # 外來鍵,
    # 如果是一對一,則外來鍵放在附加表對應的模型中
    # 如果是一對多,則外來鍵放在多的表物件的模型中
    uid = db.Column(db.Integer, db.ForeignKey(Student.id),comment="外來鍵")