开发者日志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)