开发者日志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)	
    
    
posted @ 2019-07-31 16:01  learnacode  阅读(184)  评论(0编辑  收藏  举报