1、ORM 與 SQLAlchemy 簡介
ORM 全稱 Object Relational Mapping
, 翻譯過來叫對象關係映射
。簡單的說,ORM 將數據庫中的表與面嚮對象語言中的類創建了一種對應關係。這樣,咱們要操做數據庫,數據庫中的表或者表中的一條記錄就能夠直接經過操做類或者類實例來完成。html
SQLAlchemy 是Python 社區最知名的 ORM 工具之一,爲高效和高性能的數據庫訪問設計,實現了完整的企業級持久模型。mysql
2、SQLAlchemy的使用
一、建立單表結構:sql
from sqlalchemy.ext.declarative import declarative_base # 導入基類 from sqlalchemy import Column, Integer, String # 數據類型 # Base = ORM基類 - 要按照ORM的規則定義你的類 Base = declarative_base() class Users(Base): __tablename__ = "user" # 建立ID數據字段 , 那麼ID是否是一個數據列呢? 也就是說建立ID字段 == 建立ID數據列 # id = Column(數據類型,索引,主鍵,外鍵,等等) id = Column(Integer, primary_key=True, autoincrement=True,index=True) name = Column(String(32), nullable=False) # nullable=False 不能爲空 # 打開數據庫的鏈接 -- 建立數據庫引擎 from sqlalchemy import create_engine # 建立數據庫引擎 # engine = create_engine("mysql://scott:tiger@hostname/dbname",encoding='latin1', echo=True) engine = create_engine("mysql+pymysql://root:@127.0.0.1:3306/SQLAlchemy_Pro?charset=utf8") Base.metadata.create_all(engine) # Base自動檢索全部繼承Base的ORM 對象 而且建立全部的數據表
2.單表的增刪改查:數據庫
from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine from creatTable import Users # 建立引擎 engine = create_engine("mysql+pymysql://root:@127.0.0.1:3306/SQLAlchemy_Pro?charset=utf8") Session = sessionmaker(engine) db_session = Session() # 1. 增長數據add(建立表結構的類名(字段名=添加的數據)) db_session.add(Users(name="ZWQ")) # 至關於創建一條添加數據的sql語句 db_session.commit() # 執行 db_session.close() # 結束關閉 # 批量添加 db_session.add_all([Users(name="清風徐來"), Users(name="水波不興")]) db_session.commit() db_session.close() # 2.查詢 query(表結構的類名) sqlres = db_session.query(Users) print(sqlres) # 直接翻譯輸出對應的SQL查詢語句 res = db_session.query(Users).all() # 返回表中全部數據對象 print(res)# [<creatTable.Users object at 0x00000000038A1B00>,<creatTable.Users object at 0x00000000038A1B70>] for u in res: print(u.id, u.name) res = db_session.query(Users).first() # 取第一個,返回是對象 print(res.id, res.name) res = db_session.query(Users).filter(Users.id == 3).first() # 返回符合條件查詢結果 print(res.name) res = db_session.query(Users).filter(Users.id <= 2, Users.name == "ZWQ").all() # filter中的條件能夠是模糊條件,多個條件 for u in res: print(u.id,u.name) # 3.更改數據 update({k:v}) res = db_session.query(Users).filter(Users.id == 1).update({"name":"DragonFire"}) print(res) db_session.commit() res = db_session.query(Users).update({"name":"ZWQ"}) # 所有修改,返回修改的數據個數 print(res) db_session.commit() # 4.刪除 delete()結合查詢條件刪除 res = db_session.query(Users).filter(Users.id == 1).delete() # 刪除否合條件的數據,返回刪除數量 print(res) db_session.commit() res = db_session.query(Users).delete() # 刪除表中全部數據,返回刪除數量 print(res) db_session.commit()
3.建立外鍵關聯的表結構:flask
from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() from sqlalchemy import Column,Integer,String,ForeignKey from sqlalchemy.orm import relationship class Student(Base): __tablename__ = "student" id = Column(Integer,primary_key=True) name = Column(String(32),nullable=False) sch_id = Column(Integer,ForeignKey("school.id")) # 關聯的表的字段,表間的關係 stu2sch = relationship("School",backref="sch2stu") # 寫在哪邊那邊就是正向查詢,對象間的關係,backref(反向查詢) class School(Base): __tablename__ = "school" id = Column(Integer,primary_key=True) name = Column(String(32),nullable=False) from sqlalchemy import create_engine engine = create_engine("mysql+pymysql://root:@127.0.0.1:3306/SQLAlchemy_Pro?charset=utf8") Base.metadata.create_all(engine)
四、外鍵關聯的表添加與查詢操做:session
from sqlalchemy.orm import sessionmaker
from creatTableFk import engine from creatTableFk import Student,School # 導入建立表結構的類 Session = sessionmaker(engine) db_session = Session() # 1.添加數據 db_session.add(School(name="NCU")) db_session.commit() # relationship 正向添加 stu = Student(name="清風徐來",stu2sch=School(name="NCU")) db_session.add(stu) db_session.commit() # relationship 反向添加 sch = School(name="NCU") sch.sch2stu = [Student(name="YWB"),Student(name="CT")] db_session.add(sch) db_session.commit() # 2.查詢 res = db_session.query(Student).all() for stu in res: print(stu.name,stu.stu2sch.name) # 正向跨表 res = db_session.query(School).all() for sch in res: for stu in sch.sch2stu: print(sch.name,stu.name) # 反向跨表
5.多對多的表的建立app
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, String, Integer, ForeignKey, create_engine from sqlalchemy.orm import relationship Base = declarative_base() # 多對多關聯經過第三張表關聯,sqlalchemy要本身建立第三張表 class Girl(Base): __tablename__ = "girls" id = Column(Integer, primary_key=True) name = Column(String(32), nullable=False) g2b = relationship("Boy", backref="b2g", secondary="hotels") class Boy(Base): __tablename__ = "boys" id = Column(Integer, primary_key=True) name = Column(String(32), nullable=False) class Hotel(Base): __tablename__ = "hotels" id = Column(Integer, primary_key=True) boy_id = Column(Integer, ForeignKey("boys.id"), nullable=False) girl_id = Column(Integer, ForeignKey("girls.id"), nullable=False) engine = create_engine("mysql+pymysql://root:@127.0.0.1:3306/SQLAlchemy_Pro?charset=utf8") Base.metadata.create_all(engine)
6.多對多表數據的添加與查詢:ide
from sqlalchemy.orm import sessionmaker from CreateTableM2M import engine Session = sessionmaker(engine) db_session = Session() from CreateTableM2M import Girl,Boy # 1.增長數據 # relationship 正向添加 g = Girl(name="ZLY",g2b=[Boy(name="ZWQ"),Boy(name="FSF")]) db_session.add(g) db_session.commit() # relationship 反向添加 b = Boy(name="ZS") b.b2g = [Girl(name="羅玉鳳"),Girl(name="娟兒"),Girl(name="芙蓉姐姐")] db_session.add(b) db_session.commit() # 2.查詢 # relationship 正向 res = db_session.query(Girl).all() for g in res: for b in g.g2b: print(g.name,b.name) # relationship 反向 res = db_session.query(Boy).all() for b in res: for g in b.b2g: print(b.name,g.name)
7. 高級ORM操做工具


1 from CreateTable import Users,engine 2 from sqlalchemy.orm import sessionmaker 3 from CreateTableForeignKey import Student 4 5 Session = sessionmaker(engine) 6 db_session = Session() 7 8 # 查詢數據表操做 9 # and or 10 from sqlalchemy.sql import and_ , or_,desc 11 ret = db_session.query(Users).filter(and_(Users.id > 3, Users.name == 'DragonFire')).all() 12 ret = db_session.query(Users).filter(or_(Users.id < 2, Users.name == 'DragonFire')).all() 13 14 ret = db_session.query(Users).filter( 15 or_( 16 Users.id < 2, 17 and_( 18 Users.name == 'eric', 19 Users.id > 3 20 ), 21 Users.name != "" 22 ) 23 ) 24 print(ret) 25 select * from User where id<2 or (name="eric" and id>3) or extra != "" 26 27 28 # 查詢全部數據 29 r1 = db_session.query(User).all() 30 31 查詢數據 指定查詢數據列 加入別名 32 r2 = db_session.query(Student.name.label('username'), Student.id).first() 33 print(r2.id,r2.username) # 15 NBDragon 34 35 # 表達式篩選條件 36 r3 = db_session.query(User).filter(User.name == "DragonFire").all() 37 38 # 原生SQL篩選條件 39 r4 = db_session.query(User).filter_by(name='DragonFire').all() 40 r5 = db_session.query(Users).filter_by(name='DragonFire').first() 41 42 字符串匹配方式篩選條件 並使用 order_by進行排序 43 r6 = db_session.query(Student).order_by(Student.name.desc()).all() 44 for i in r6: 45 print(i.id,i.name) 46 47 原生SQL查詢 48 from sqlalchemy.sql import text 49 r7 = db_session.query(User).from_statement(text("SELECT * FROM User where name=:name")).params(name='DragonFire').all() 50 51 # 篩選查詢列 52 # query的時候咱們不在使用User ORM對象,而是使用User.name來對內容進行選取 53 user_list = db_session.query(User.name).all() 54 print(user_list) 55 for row in user_list: 56 print(row.name) 57 58 # 別名映射 name as nick 59 user_list = db_session.query(User.name.label("nick")).all() 60 print(user_list) 61 for row in user_list: 62 print(row.nick) # 這裏要寫別名了 63 64 # 篩選條件格式 65 user_list = db_session.query(User).filter(User.name == "DragonFire").all() 66 user_list = db_session.query(User).filter(User.name == "DragonFire").first() 67 user_list = db_session.query(User).filter_by(name="DragonFire").first() 68 for row in user_list: 69 print(row.nick) 70 71 # 複雜查詢 72 from sqlalchemy.sql import text 73 user_list = db_session.query(User).filter(text("id<:value and name=:name")).params(value=3,name="DragonFire") 74 75 # 查詢語句 76 from sqlalchemy.sql import text 77 user_list = db_session.query(User).filter(text("select * from User id<:value and name=:name")).params(value=3,name="DragonFire") 78 79 # 排序 : 80 user_list = db_session.query(User).order_by(User.id).all() 81 user_list = db_session.query(User).order_by(User.id.desc()).all() 82 for row in user_list: 83 print(row.name,row.id) 84 85 #其餘查詢條件 86 """ 87 ret = session.query(User).filter_by(name='DragonFire').all() 88 ret = session.query(User).filter(User.id > 1, User.name == 'DragonFire').all() 89 ret = session.query(User).filter(User.id.in_(session.query(User.id).filter_by(name='DragonFire'))).all() 子查詢 90 from sqlalchemy import and_, or_ 91 ret = session.query(User).filter(and_(User.id > 3, User.name == 'DragonFire')).all() 92 ret = session.query(User).filter(or_(User.id < 2, User.name == 'DragonFire')).all() 93 94 95 96 97 # 限制 98 ret = db_session.query(User)[1:2] 99 100 # 排序 101 ret = db_session.query(User).order_by(User.name.desc()).all() 102 ret = db_session.query(User).order_by(User.name.desc(), User.id.asc()).all() 103 104 # 分組 105 from sqlalchemy.sql import func 106 107 ret = db_session.query(User).group_by(User.extra).all() 108 ret = db_session.query( 109 func.max(User.id), 110 func.sum(User.id), 111 func.min(User.id)).group_by(User.name).all() 112 113 ret = db_session.query( 114 func.max(User.id), 115 func.sum(User.id), 116 func.min(User.id)).group_by(User.name).having(func.min(User.id) >2).all() 117 """ 118 119 # 關閉鏈接 120 db_session.close() 121 122 123 ret = db_session.query(Student).filter(Student.id.between(1, 3)).all() # between 大於1小於3的 124 for i in ret: 125 print(i.id,i.name) 126 ret = db_session.query(Student).filter(~Student.id.in_([1,4])).all() # in_([1,3,4]) 只查詢id等於1,3,4的 127 for i in ret: 128 print(i.id,i.name) 129 ret = session.query(User).filter(~User.id.in_([1,3,4])).all() # ~xxxx.in_([1,3,4]) 查詢不等於1,3,4的 130 # 通配符 131 ret = db_session.query(Student).filter(Student.name.like('%e%')).all() 132 133 134 ret = db_session.query(Student).filter(~Student.name.like('Z%')).all() 135 for i in ret: 136 print(i.id,i.name) 137 138 139 140 高級版更新操做 141 from my_create_table import User,engine 142 from sqlalchemy.orm import sessionmaker 143 144 Session = sessionmaker(engine) 145 db_session = Session() 146 147 #直接修改 148 db_session.query(Student).filter(Student.id > 3).update({Student.name: Student.name + "099"}, synchronize_session=False) 149 db_session.commit() 150 151 db_session.query(Student).filter(Student.id > 3).update({"name": Student.name + "123"}, synchronize_session=False) 152 db_session.commit() 153 154 155 #在原有值基礎上添加 - 1 156 db_session.query(User).filter(User.id > 0).update({User.name: User.name + "099"}, synchronize_session=False) 157 158 #在原有值基礎上添加 - 2 159 db_session.query(User).filter(User.id > 0).update({"age": User.age + 1}, synchronize_session="evaluate") 160 db_session.commit()
3、Flask_SQLAlchemy
1. 安裝 Flask-SQLAlchemy模塊,pip安裝 性能
pip install Flask-SQLAlchemy
2.先建立一個Flask項目
3.基於這個Flask項目,加入Flask-SQLAlchemy讓項目變得生動起來
1 from flask import Flask 2 3 # 導入Flask-SQLAlchemy中的SQLAlchemy 4 from flask_sqlalchemy import SQLAlchemy 5 6 # 實例化SQLAlchemy 7 db = SQLAlchemy() 8 # PS : 實例化SQLAlchemy的代碼必需要在引入藍圖以前 9 10 from .views.users import user 11 12 13 def create_app(): 14 app = Flask(__name__) 15 16 # 初始化App配置 這個app配置就厲害了,專門針對 SQLAlchemy 進行配置 17 # SQLALCHEMY_DATABASE_URI 配置 SQLAlchemy 的連接字符串兒 18 app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:DragonFire@127.0.0.1:3306/dragon?charset=utf8" 19 # SQLALCHEMY_POOL_SIZE 配置 SQLAlchemy 的鏈接池大小 20 app.config["SQLALCHEMY_POOL_SIZE"] = 5 21 # SQLALCHEMY_POOL_TIMEOUT 配置 SQLAlchemy 的鏈接超時時間 22 app.config["SQLALCHEMY_POOL_TIMEOUT"] = 15 23 app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False 24 25 # 初始化SQLAlchemy , 本質就是將以上的配置讀取出來 26 db.init_app(app) 27 28 app.register_blueprint(user) 29 30 return app 31 32 MyApp/__init__.py
4.創建models.py ORM模型文件
1 from MyApp import db 2 3 Base = db.Model # 這句話你是否還記的? 4 # from sqlalchemy.ext.declarative import declarative_base 5 # Base = declarative_base() 6 # 每一次咱們在建立數據表的時候都要作這樣一件事 7 # 然而Flask-SQLAlchemy已經爲咱們把 Base 封裝好了 8 9 # 創建User數據表 10 class Users(Base): # Base實際上就是 db.Model 11 __tablename__ = "users" 12 __table_args__ = {"useexisting": True} 13 # 在SQLAlchemy 中咱們是導入了Column和數據類型 Integer 在這裏 14 # 就和db.Model同樣,已經封裝好了 15 id = db.Column(db.Integer,primary_key=True) 16 username = db.Column(db.String(32)) 17 password = db.Column(db.String(32)) 18 19 20 if __name__ == '__main__': 21 from MyApp import create_app 22 app = create_app() 23 # 這裏你要回顧一下Flask應用上下文管理了 24 # 離線腳本: 25 with app.app_context(): 26 db.drop_all() 27 db.create_all() 28 29 MyApp/models.py
5.實現一個簡單的用戶管理,登陸視圖
1 from flask import Blueprint, request, render_template, redirect 2 from MyApp.models import User,db 3 4 users = Blueprint("user",__name__) 5 6 @users.route("/add_user",methods=["POST","GET"]) 7 def add_user(): 8 if request.method == "GET": 9 return render_template("add_user.html") 10 else: 11 username = request.form.get("username") 12 db.session.add(User(name=username)) 13 db.session.commit() 14 return redirect("/user_list") 15 16 @users.route("/user_list",methods=["POST","GET"]) 17 def user_list(): 18 res = User.query.all() 19 print(res) 20 return render_template("user_list.html",user_list=res) 21 22 23 @users.route("/del/<uid>",methods=["POST","GET"]) 24 def delete_user(uid): 25 res = User.query.filter(User.id == int(uid)).delete() 26 db.session.commit() 27 print(res) 28 return redirect("/user_list") 29 30 31 32 @user.route("/login",methods=["POST","GET"]) 33 def user_login(): 34 if request.method == "POST": 35 username = request.form.get("username") 36 password = request.form.get("password") 37 38 # SQlalchemy須要這樣作 39 # from sqlalchemy.orm import sessionmaker 40 # Session = sessionmaker(engine) 41 # db_sesson = Session() 42 # 如今不用了,由於 Flask-SQLAlchemy 也已經爲咱們作好會話打開的工做 43 # 咱們在這裏作個弊: 44 db.session.add(Users(username=username,password=password)) 45 db.session.commit() 46 47 # 而後再查詢 48 user_info = Users.query.filter(Users.username == username and User.password == password).first() 49 print(user_info.username) 50 if user_info: 51 return f"登陸成功{user_info.username}" 52 53 return render_template("login.html")
其實Flask-SQLAlchemy比起SQLAlchemy更加的簡單自如,用法幾乎如出一轍,就是在配置和啓動上須要注意與Flask的配合就好啦