開發者日誌sqlalchemy 7.31

開發者日誌sqlalchemy 7.31

sqlalchemy 建立表

1. 使用sqlalchemy建立一個表

  • 引入方法前端

    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String
    
    Model = declarative_base()  # 建立基類,至關於Django中的 models.Model,被各個數據表類所繼承
  • 建立表mysql

    class Users(Model):                  # Users是對象
        __tablename__ = 'users'         # 映射到數據的表
        id = Column(Integer, primary_key=True, autoincrement=True)  # 主鍵 自增
        name = Column(String(32), index=True, nullable=False, unique=True)   # 普通索引  排序用到  1是索引2是首字母 重複首字母 看索引
  • 使用引擎建立數據庫sql

    # 建立數據庫的引擎
    from sqlalchemy.engine import create_engine
    
    engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/sqlalchemy?charset=utf8")
    
    # 檢索全部繼承 Model 的Object 並在 engine 指向的數據庫中建立 全部的表
    Model.metadata.create_all(engine)
    # Model.metadata.drop_all(engine)   # 刪除全部

1564559679847

關於索引,數據庫

上面的建立表的形式使BTREE索引,還有hash索引flask

Hash 索引結構的特殊性,其檢索效率很是高,索引的檢索能夠一次定位,不像B-Tree 索引須要從根節點到枝節點,最後才能訪問到頁節點這樣屢次的IO訪問,因此 Hash 索引的查詢效率要遠高於 B-Tree 索引。

參考博客:https://blog.csdn.net/kidoo1012/article/details/70207519session

2. 增刪改查 crud

create read update deleteapp

  • 引入數據庫,以及引擎窗口操做函數

    from sqlalchemy.orm import sessionmaker     # 建立數據表操做對象 sessionmaker
    from create_table import engine, Users    # 導入引擎
    session = sessionmaker(engine)      # 新建 sqlalchemy 這個數據庫的查詢窗口
    db_session = session()      # 打開查詢窗口
  • 增長數據.net

    u = Users(name='JWB')   # 新建insert語句  = insert into
    db_session.add(u)         # 將insert語句移動到 db_session 查詢窗口
    db_session.commit()     # 執行查詢窗口中的全部語句
    db_session.close()      # 關閉查詢窗口
  • 增長多條數據日誌

    u_list = [Users(name='YWB'), Users(name='dragonfire')]   # 新建insert語句  = insert into
    db_session.add_all(u_list)   # 將insert語句移動到 db_session 查詢窗口
    db_session.commit()     # 執行查詢窗口中的全部語句
    db_session.close()      # 關閉查詢窗口
  • 查詢數據

    res = db_session.query(Users).all()   # 查詢全部數據
    # [<create_table.Users object at 0x00000000038ADC18>, <create_table.Users object at 0x00000000038ADBA8>]  
    
    res = db_session.query(Users)   # 不寫默認是all,可是不提倡
    for u in res:
        print(u.id, u.name)
    res = db_session.query(Users).first()   # 第一條數據
    print(res.id, res.name)
    #2    ausir   #  存入了普通索引,在name裏, 按首字母排序
    #3    dragonfire
    #1    JWB
  • 簡單帶條件的查詢

    res = db_session.query(Users).filter(Users.id < 3).all()
    
    res = db_session.query(Users).filter(Users.id < 3)  # 不寫all 就會查詢出mysql語句
    #SELECT users.id AS users_id, users.name AS users_name
    #FROM users
    #WHERE users.id < %(id_1)s     # 可是循環依舊能夠得到id ,和 name值
    print(res)
    for u in res:
        print(u.id, u.name)
  • 並列條件

    res = db_session.query(Users).filter(Users.id < 3, Users.name == 'YWB').all()
    print(res)
    for u in res:
        print(u.id, u.name)
  • 修改數據類型

    # 先查後修改

    db_session.query(Users).filter(Users.id == 2).update({'name': 'wusir', 'age': 333})
    # 修改沒有的會報錯 sqlalchemy.exc.InvalidRequestError: Entity '<class 'create_table.Users'>' has no property 'age'
    db_session.query(Users).filter(Users.id == 2).update({'name': 'ausir'})
    # 更新的sql語句
    db_session.commit()

3. 一對多 建立 ForeignKey

  • 引入外鍵和關係

    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String, ForeignKey
    
    from sqlalchemy.orm import relationship     # 是個 函數 ,不是s 一個py文件 # ORM精髓所在
    Model = declarative_base()
  • 建立表

    # 建立表
    class Student(Model):                  # Users是對象
        __tablename__ = 'student'         # 映射到數據的表
        id = Column(Integer, primary_key=True, autoincrement=True)  
        name = Column(String(32), index=True, nullable=False, unique=True) 
    
        # 關聯字段,讓sch_id 與 shcool 的 id 進行關聯,主外鍵關係(這裏的ForeignKey必定要是表名.id不是對象名)
        sch_id = Column(Integer, ForeignKey('school.id'))   # 多對一關係存儲列
        # 將student 與 school 建立關係 這個不是字段,只是關係,backref是反向關聯的關鍵字
        stu2sch = relationship('School', backref='sch2stu')    # 這裏是對象名
    
    class School(Model):  # Users是對象
        __tablename__ = 'school'  # 映射到數據的表
        id = Column(Integer, primary_key=True, autoincrement=True)   
        name = Column(String(32), index=True, nullable=False, unique=True)
  • 引擎更新

    from sqlalchemy.engine import create_engine
    
    engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/sqlalchemy?charset=utf8")
    
    Model.metadata.create_all(engine)

    外鍵

    1564563676734

    今日錯誤,School中間多加了個o,浪費了30分鐘

4 curd foreign

  • 不寫對應外鍵的id,也能夠加入進去,可是沒有關聯

    1564565850247

  • 複雜寫法 添加

    # 增長一條數據
    # 優先增長school
    sc = School(name='EDUBeijing')
    db_session.add(sc)
    db_session.commit()
    # # 再添加student
    sch_fir = db_session.query(School).filter(School.name == 'EDUBeijing').first()
    stu = Student(name='DF', sch_id=sch_fir.id)
    # stu = Student(name='DF')         # 不寫對應外鍵的id,
    db_session.add(stu)
    db_session.commit()
  • 添加數據 relationship 正向添加數據

    stu = Student(name='DF',stu2sch=School(name='EDUBeijing'))
    db_session.add(stu)
    db_session.commit()
  • 添加數據 relationship 反向添加數據

    sch = School(name='EDUShanghai')
    sch.sch2stu = [
        Student(name='haifeng'),
        Student(name='hai')
    ]
    db_session.add(sch)
    db_session.commit()
  • 查詢的 relationship 正向

    res = db_session.query(Student).all()
    for stu in res:
        print(stu.id, stu.name,stu.stu2sch.name)

    結果:

    1 DF EDUBeijing
    2 DF EDUBeijing
    4 DF EDUBeijing
    5 haifeng EDUShanghai
    6 hai EDUShanghai
  • 查詢的 relationship 反向向

res = db_session.query(School).all()
for sch in res:
    # print(len(sch.sch2stu), sch.name)
    for stu in sch.sch2stu:
        print(sch.name,stu.name)

結果

學生長度,學校
各個學生的名字, 所屬學校

1對多時,外鍵寫到多的那

5 添加多對多的表

  • 建立表

    class Girls(Model):                  # Users是對象
        __tablename__ = 'girl'         # 映射到數據的表
        id = Column(Integer, primary_key=True )  # 主鍵 自增
        name = Column(String(32), nullable=False)   
    
        g2b = relationship('Boys', backref='b2g', secondary='hotel')    # 這裏是對象名
    
    class Boys(Model):  # Users是對象
        __tablename__ = 'boy'  # 映射到數據的表
        id = Column(Integer, primary_key=True)  # 主鍵 自增
        name = Column(String(32), nullable=False)   
    
    class Group(Model):  # Users是對象       外鍵在這裏
        __tablename__ = 'group'  # 映射到數據的表
        id = Column(Integer, primary_key=True)
        boy_id = Column(Integer, ForeignKey("boy.id"))
        girl_id = Column(Integer, ForeignKey("girl.id"))
  • 數據庫添加狀況

    1564567572706

    1564567585960

    1564567600099

6 crud m2m

  • 添加數據 之 relationship 正向添加數據

    g = Girls(name='g1', g2b=[Boys(name='b1'), Boys(name='b2')])
    db_session.add(g)
    db_session.commit()
  • 添加數據 之 relationship 反向添加數據

    b = Boys(name='B3')
    b.b2g = [
        Girls(name="G2"),
        Girls(name="G3"),
    ]
    db_session.add(b)
    db_session.commit()

    group 存的表關係

    1564568248384

  • 查詢數據 之 relationship 正向

    res = db_session.query(Girls).all()
    for g in res:
        for b in g.g2b:
            print(g.name, b.name)
  • 查詢數據 之 relationship 反向

    res = db_session.query(Boys).all()
    for b in res :
        for g in b.b2g:
            print(b.name, g.name)

    結果顯示

    ...
    G2 B3
    G3 B3
    b1 g1
    b2 g1
    ...

寫一個 app的flask-sqlalchemy

文件格式以下(像Django)

sql
    app01
        static
        templates       
        views   
            user.py     # 寫數據庫增刪改查邏輯,經過flask路由前端操做   4
        __init__.py     # 寫app,並把數據庫的引擎等配置寫入app     1
        models.py       # 寫數據庫表對象   3   
    manager.py          # 執行app     2
  • 執行manager程序

    from app01 import create_app
    app = create_app()  # 運行主程序
    
    if __name__ == '__main__':
        app.run()
  • 首先走__init__.py

    from flask import Flask
    from app01.models import db
    from app01.views import user
    
    def create_app():   # 配置app,以及把數據庫的引擎加入app , 給model使用
        app = Flask(__name__)
        app.config['DEBUG'] = True
        app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123@127.0.0.1:3306/sqlalchemy?charset=utf8'
        app.config["SQLALCHEMY_POOL_SIZE"] = 50
        app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    
        db.init_app(app)    # 初始化app
        app.register_blueprint(user.user_bp)
    
        return app
  • model.py裏新建了數據庫表 , 經過flask_sqlalchemy (封裝了sqlalchemy的經常使用功能,更簡潔)

    from flask_sqlalchemy import SQLAlchemy   
    
    db = SQLAlchemy()   # 封裝了SQLALchemy   
    
    class Users(db.Model):      #  寫對象(表) 
        __tablename__ = 'users_flask' 
        id = db.Column(db.Integer, primary_key=True)    # db裏都封裝了(flask_sqlalchemy)   
        name = db.Column(db.String(32), nullable=False)     # db.Column 不像sqlalchemy都得導入
    
    if __name__ == '__main__':
        from app01 import create_app  
        app = create_app()    
        db.create_all(app=app) #建立對象 = Model.metadata.create_all(engine)
  • 此處寫對錶的增刪改查邏輯,在視圖裏寫

    from flask import Blueprint
    from app01.models import Users, db    # 傳過Users表和 db數據庫
    
    user_bp = Blueprint('user_bp', __name__)
    
    # 增刪改查邏輯     傳參   #增
    @user_bp.route('/add_user/<username>', methods=['POST', 'get'])
    def add_user(username):
        u = Users(name=username)
        db.session.add(u)
        db.session.commit()
        return '200ok i am user_bp'
    # 查
    @user_bp.route('/get_user/<username>', methods=['POST', 'get'])
    def get_user(username):
        u = Users.query.filter(Users.name == username).first()    
        return str(u.id)
相關文章
相關標籤/搜索