• SQLALchemy之增删改查、一对多、多对多


    SQLALchemy之增删改查、一对多、多对多

    • Django 的 Models 仅仅只是配置和使用比较简单,因为他是Django自带的ORM框架,也正是因为是Django原生的,所以兼容性远远不如SQLAlchemy

    • 真正算得上全面的ORM框架必然是我们的SQLAlchemy ORM框架,它可以在任何使用SQL查询时使用

    建表

    # ORM中的数据表是什么呢?
    # Object Relation Mapping
    # Object - Table 通过 Object 去操纵数据表
    # 从而引出了我们的第一步创建数据表 - 创建Object
    # 1. 创建Object
    # class User(object):
    #     pass
    
    # 让object与table产生某种关系,也就是让object与数据表格式极度相似
    # 导入官宣基本模型
    from sqlalchemy.ext.declarative import declarative_base
    Base = declarative_base()  #实例化官宣模型----base就是官宣模型
    # 当前的这个Object继承了Base也就是代表了Object继承了ORM的模型
    class User(Base):  #相当于django中的Models中的Model
        #为table创建名称
        __tablename__ = "User"
        #创建id字段
        from sqlalchemy import Column,Integer,String
        # id = Column(数据类型,索引,主键,外键,等等)
        # int == Integer
        id = Column(Integer,primary_key=True,autoincrement=True)
        # str == char(长度) == String(长度)
        name = Column(String(32), index=True)
    
    from sqlalchemy import create_engine
    # 连接数据库,创建数据库引擎
    engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/chartset=utf8")
    # base 自动检索所有继承orm的对象  并且创建所有的数据表
    Base.metadata.create_all(engine)
    
    

    添加数据

    # insert into user(name) values('maqian')  ----sql语句
    
    # orm中的操作
    from SQLAlchemy_test.my_table import User  # 导入之前创建好的对象
    
    # 创建一条数据
    user1 = [User(id=1, name='maqian'),
             User(id=2, name='aqian'),
             User(id=3, name='baqian'),
             User(id=4, name='caqian')]
    # 写入数据库: 打开数据库会话,即创建一个操作数据库的窗口
    from sqlalchemy.orm import sessionmaker
    from SQLAlchemy_test.my_table import engine  # 导入之前创建好的数据库引擎
    
    Session = sessionmaker(engine)  # 创建会话对象,并将engine交给会话对象
    db_session = Session()  # 打开会话对象
    db_session.add_all(user1)  # 在会话中添加orm中user模型中的一条数据
    db_session.commit()  # 会话提交
    db_session.close()  # 关闭会话
    

    查找

    from SQLAlchemy_test.my_table import User, engine
    from sqlalchemy.orm import sessionmaker
    
    Session = sessionmaker(engine)  # 创建session会话对象
    db_session = Session()  # 开启session会话
    
    user_list = db_session.query(User).all()  #取出所有数据
    # [<SQLAlchemy_test.my_table.User object at 0x00000273D4F13C08>,
    #   <SQLAlchemy_test.my_table.User object at 0x00000273D4F13EC8>]
    print(user_list)
    for i in user_list:
        print(i.id,i.name)  #取出真正的数据
    
    db_session.close()  #关闭session会话
    
    user_list = db_session.query(User).filter(User.id <= 1).all()  #取出id小于1的所有数据
    print(user_list)
    for i in user_list:
        print(i.id,i.name)  #取出真正的数据
    db_session.close()
    

    查找进阶

    from SQLAlchemy_test.my_table import User,engine
    from sqlalchemy.orm import sessionmaker
    Session = sessionmaker(engine)
    db_session = Session()
    
    #查询数据表操作
    from sqlalchemy.sql import or_,and_
    ret = db_session.query(User).filter(and_(User.id >=0,User.name=='maqian')).all()
    ret1 = db_session.query(User).filter(or_(User.id >=0,User.name=='maqian')).all()
    db_session.close()
    
    #查询所有数据
    res = db_session.query(User).all()
    
    #查询数据 指定查询列  加上别名
    r2 = db_session.query(User.name.label('username'),User.id).first()
    print(r2.id,r2.username)  #0 haven
    
    #表达式删选条件
    r3 = db_session.query(User).filter(User.name=='haven').all()
    print(r3)
    #原生sql筛选条件
    r4 = db_session.query(User).filter_by(name='haven').all()
    r5 = db_session.query(User).filter_by(name='haven').first()
    
    #字符串匹配方式删选条件,并使用order_by排序
    # r6 = db_session.query(User).filter(text('id<:value and name=:name')).params(value=224,name='haven').order_by(User.id).all()
    
    #原生sql查询
    # r7 = db_session.query(User).from_statement(text("select * from user where name =:haven")).parmas(
    #     name = 'haven').all()
    
    #筛选查询列
    r8 = db_session.query(User.name).all()
    for i in r8:
        print(i.name)
    
    #别名映射 name as nick
    r9 = db_session.query(User.name.label('nick')).all()
    for i in r9:
        print(i.nick)
    
    #复杂查询
    from sqlalchemy.sql import text
    r10 = db_session.query(User).filter(text('id<:value and name=:name')).params(value=224,name='haven').order_by(User.id).all()
    print(r10)
    
    #排序
    # user_list = db_session.query(User).order_by(User.id).all()
    user_list = db_session.query(User).order_by(User.id.desc()).all()
    for i in user_list:
        print(i.id,i.name)
    db_session.close()
    

    from SQLAlchemy_test.my_table import User,engine
    from sqlalchemy.orm import sessionmaker
    
    Session = sessionmaker(engine)
    db_session = Session()
    
    #跟新表里面某条sql语句  update 表名 set 字段名=‘值’ where 条件
    res = db_session.query(User).filter(User.id==1).update({'name':'haven'})  #更新一条
    print(res)  # 1 res是更新语句所更新的行数
    
    db_session.commit()  #数据的增、改、删操作要进行提交
    db_session.close()
    
    res = db_session.query(User).filter(User.id<=1).update({'name':'haven'})  #更新多条
    print(res)  # 2 res是更新语句所更新的行数
    
    db_session.commit()  #数据的增、改、删操作要进行提交
    db_session.close()
    

    改--进阶

    from sqlalchemy.orm import sessionmaker
    from SQLAlchemy_test.my_table import User,engine
    Session = sessionmaker(engine)
    db_session = Session()
    
    #直接修改
    db_session.query(User).filter(User.id > 0).update({'name':'maqian'})
    
    #在原有的基础上添加 -1
    db_session.query(User).filter(User.id > 0).update({User.name:User.name + '099'},synchronize_session=False)
    lst = db_session.query(User).all()
    for i in lst:
        print(i.id,i.name)
    
    #在原有基础值上添加 -2
    db_session.query(User).filter(User.id>1).update({"age":User.age + 1},synchronize_session = 'evaluate')
    db_session.commit()
    

    from SQLAlchemy_test.my_table import User,engine
    from sqlalchemy.orm import sessionmaker
    Session = sessionmaker(engine)
    db_session = Session()
    
    #删除一条数据 sql  delete from 表名 where 条件
    
    res = db_session.query(User).filter(User.id == 1).delete()
    print(res)  # 1  删除数据的行数
    db_session.commit()
    db_session.close()
    

    一对多

    建表

    # 创建表及表关系relationship
    from sqlalchemy import Column, Integer, String, ForeignKey
    from sqlalchemy.orm import relationship
    from sqlalchemy.ext.declarative import declarative_base
    
    Base = declarative_base()
    
    
    class Class_Table(Base):
        __tablename__ = 'classtable'
        id = Column(Integer, primary_key=True)
        name = Column(String(32), index=True)
    
    
    class Student(Base):
        __tablename__ = 'student'
        id = Column(Integer, primary_key=True)
        name = Column(String(32), index=True)
        # 关联字段,使class_id与classtable的id进行关联,这里的外键一定是表名.字段
        class_id = Column(Integer, ForeignKey('classtable.id'))
        # 将Student与Class_Table创建关系,这个不是字段,只是关系,back_ref是反向关联的关键字
        to_class = relationship('Class_Table', backref='s_class')
    
    
    from sqlalchemy import create_engine
    
    # 连接数据库,创建数据库引擎
    engine = create_engine('mysql+pymysql://root:123@127.0.0.1:3306/orm_test?charset=utf8')
    Base.metadata.create_all(engine)
    

    添加

    from SQLAlchemy_test.my_foreign_key import Class_Table, Student, engine
    from sqlalchemy.orm import sessionmaker
    
    Session = sessionmaker(engine)
    db_session = Session()
    
    # 添加两个班级
    lst = [Class_Table(id=0, name='class1'),
           Class_Table(id=1, name='c_21'),
           Class_Table(id=2, name='c_31'),
           Class_Table(id=3, name='c_41'),
           Class_Table(id=4, name='c_51')]
    db_session.add_all(lst)
    db_session.commit()
    
    
    # 添加一个学生 douzi  班级是 class1
    #
    # 查询要添加的班级
    class_obj = db_session.query(Class_Table).filter(Class_Table.name == 'class1').first()
    # 创建学生
    stu = Student(name='douzi', class_id=class_obj.id)
    db_session.add(stu)
    db_session.commit()
    
    #relationship版添加数据,通过 to_class 可以做到两件事
           # 1.在classtable中添加一条数据
           # 2.在student中添加一条数据,并将刚才添加到classtable中的数据id与student中的class_id关联起来
    # 反向添加数据
    class_obj = Class_Table(name='python')
    # 通过class_obj中的反向关联字段backref='s_class'
    #在sutdent中添加两条数据,并将2条数据的class_id写成class_obj的id
    class_obj.s_class = [Student(name='zhouzhou'),Student(name='yueyue')]
    db_session.add(class_obj)
    db_session.commit()
    db_session.close()
    

    from SQLAlchemy_test.my_foreign_key import Class_Table,Student,engine
    from sqlalchemy.orm import sessionmaker
    Session = sessionmaker(engine)
    db_session = Session()
    
    #显示所有数据,班级名称,链表查询
    stu_list = db_session.query(Student).all()
    for i in stu_list:
        print(i.id,i.name,i.class_id)
    
    #反向查询
    class_lst = db_session.query(Class_Table).all()
    for i in class_lst:
        for n in i.s_class:
            print(i.name,n.name)
            #i.s_class 通过backref中的s_class反向关联到student表中的ID获取name
    

    from SQLAlchemy_test.my_foreign_key import Class_Table,Student,engine
    from sqlalchemy.orm import sessionmaker
    Session = sessionmaker(engine)
    db_session = Session()
    
    class_info = db_session.query(Class_Table).filter(Class_Table.name=='python').first()
    db_session.query(Student).filter(Student.class_id==class_info.id).update({'name':'java'})
    
    db_session.commit()
    db_session.close()
    

    from SQLAlchemy_test.my_foreign_key import Class_Table,Student,engine
    from sqlalchemy.orm import sessionmaker
    Session = sessionmaker(engine)
    db_session = Session()
    
    #删除
    class_info = db_session.query(Class_Table).filter(Class_Table.name == 'class1').first()
    db_session.query(Student).filter(Student.id == class_info.id).delete()
    db_session.commit()
    db_session.close()
    

    多对多

    建表

    from sqlalchemy.ext.declarative import declarative_base
    
    Base = declarative_base()
    from sqlalchemy import Column, String, ForeignKey, Integer
    from sqlalchemy.orm import relationship
    
    
    class School(Base):
        __tablename__ = 'school'
        id = Column(Integer, primary_key=True)
        girl_id = Column(Integer, ForeignKey('girl.id'))
        boy_id = Column(Integer, ForeignKey('boy.id'))
    
    
    class Boy(Base):
        __tablename__ = 'boy'
        id = Column(Integer, primary_key=True)
        name = Column(String(32), index=True)
        # 创建关系
        girls = relationship('Girl', secondary='school', backref='girl2boy')
    
    
    class Girl(Base):
        __tablename__ = 'girl'
        id = Column(Integer, primary_key=True)
        name = Column(String(32), index=True)
    
    
    from sqlalchemy import create_engine
    
    engine = create_engine('mysql+pymysql://root:123@127.0.0.1:3306/orm_test?charset=utf8')
    Base.metadata.create_all(engine)
    
    

    添加

    from SQLAlchemy_test.my_M2M import School, Boy, Girl, engine
    from sqlalchemy.orm import sessionmaker
    
    Session = sessionmaker(engine)
    db_session = Session()
    
    # 通过Boy添加girl和school数据
    # boy = Boy(name='吴亦凡3')
    boy = db_session.query(Boy).filter(Boy.name == "吴亦凡2").first()
    girl = db_session.query(Girl).filter(Girl.name == "赵丽颖").first()
    boy.girls = [girl]
    # db_session.add(boy)
    db_session.commit()
    
    # 通过girl添加BOY和school数据
    
    # girl = Girl(name='杨幂')
    # girl.girl2boy = [Boy(name='周杰伦')]
    # db_session.add(girl)
    # db_session.commit()
    
    

    查找

    from SQLAlchemy_test.my_M2M import School, Boy, Girl, engine
    from sqlalchemy.orm import sessionmaker
    
    Session = sessionmaker(engine)
    db_session = Session()
    
    # 通过boy查询所有的girl----反向查找
    school = db_session.query(Girl).all()
    for row in school:
        for row2 in row.girl2boy:
            print(row.name, row2.name)
    
    # 通过girl查询boy----正向查找
    school = db_session.query(Boy).all()
    for row in school:
        for row2 in row.girls:
            print(row.name, row2.name)
    
    
  • 相关阅读:
    7种jvm垃圾回收器,这次全部搞懂
    3分钟学会redis主从复制搭建,及原理
    一文搞懂什么是递归,程序员必会算法之一
    Redis持久化方式:RDB和AOF详解,对比
    jvm垃圾回收算法详解,看这一篇就够了(求点赞)
    Redis命令大全,满足你的日常工作,看这一篇就够了(求点赞)
    Java自定义异常为什么性能差(求点赞)阿里双十一的性能凶手之一
    jvm类加载器,类加载机制详解,看这一篇就够了(求点赞)
    show processlist 命令详解,MySQL优化看这一篇就够了
    asp.net中的post和get请求操作
  • 原文地址:https://www.cnblogs.com/maqian/p/13352157.html
Copyright © 2020-2023  润新知