• 开发者日志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,被各个数据表类所继承
      
      
    • 创建表

      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是首字母 重复首字母 看索引
      
    • 使用引擎创建数据库

      # 创建数据库的引擎
      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索引

    Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索引。
    

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

    2. 增删改查 crud

    create read update delete

    • 引入数据库,以及引擎窗口操作

      from sqlalchemy.orm import sessionmaker     # 创建数据表操作对象 sessionmaker
      from create_table import engine, Users    # 导入引擎
      session = sessionmaker(engine)      # 新建 sqlalchemy 这个数据库的查询窗口
      db_session = session()      # 打开查询窗口
      
    • 增加数据

      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)	
      
      
  • 相关阅读:
    Go语言学习资源
    优秀编程学习网站
    我对架构的理解
    【转】TCP协议中的三次握手和四次挥手(图解)
    【转】asp.net c# 网上搜集面试题目大全(附答案)
    spring framework 4 源码阅读
    浮点类型
    把二元查找树转变成排序的双向链表
    用模板写快速排序-链表
    用模板写快速排序-数组
  • 原文地址:https://www.cnblogs.com/Doner/p/11276941.html
Copyright © 2020-2023  润新知