• python ORM框架:SqlAlchemy


      ORM,对象关系映射,即Object Relational Mapping的简称,通过ORM框架将编程语言中的对象模型与数据库的关系模型建立映射关系,这样做的目的:简化sql语言操作数据库的繁琐过程(原生sql的编写及拼接等),转而直接使用对象模型来操作数据库做替代

    第一部分

          SqlAlchemy本身无法直接操作数据库,它是建立在第三方数据库API(如python 中的pymysql库)之上,应用程序调用对象模型进行增删改查等操作时,将对象转化成sql语句,然后再通过API调用执行已经转换好的sql语句

    安装

      pip install sqlalchemy
      pip install pymysql #这里笔者使用的数据API是pymysql
    

    应用

    - 配置及创建数据库引擎

          SqlAlchemy 支持间接调用多种数据库API,根据不能的配置文件调用不同的数据库API

    #常见配置文件:即database url,创建数据库引擎需要
    MySQL-Python:mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
    
    pymysql:mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
    
    MySQL-Connector:mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname>
    
    cx_Oracle:oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...]
    
    - 创建数据库引擎

          * 注意 *:带上charset=utf8参数,防止中文乱码

    #初始化数据库连接
    from sqlalchemy import create_engine
    url="mysql+pymysql://[账号]:[密码]@[主机]:[端口]/[数据库]?charset=utf8" #这里笔者使用的mysql数据库,pymysql API与数据库交互,添加的charset可防止中文乱码
    engine=create_engine(url,echo=False,encoding="utf-8")  #url为配置文件,echo调试参数,值为为true打印整个sql执行过程
    
    - 创建会话(session)

          通过sessionmaker工厂方法,我们得到一个类,默认返回Session类,也可以自定义Session类
    方法:
    sessionmaker( bind=None, class_=Session, autoflush=True,autocommit=False,expire_on_commit=True,info=None, **kw)

    #示例1:直接调用sessionmaker
    from sqlalchemy.orm import sessionmaker
    SessionClass=sessionmaker(bind=engine)#利用工厂模式获取SessionClass
    session_obj=SessionClass() #创建session对象,此时已绑定数据库引擎,但是未关联任何的对象模型
    
    #示例1:使用scoped_session
    from sqlalchemy.orm import scoped_session
    SessionClass=scoped_session(sessionmaker(bind=engine))#利用工厂模式获取SessionClass
    session_obj=SessionClass() #创建session对象,此时已绑定数据库引擎,但是未关联任何的对象模型
    

    scoped_session VS Session
          Session:多次创建的Session对象是不同的
          scoped_session:首先通过sessionmaker工厂创建Session对象,然后对Session对象进行相应的管理(先在Registry中找之前是否创建过Session,若没有,则创建并注册,有,则直接返回),这样的目的:同一个线程维护一个session对象,保证了线程的安全性

    - 与数据库交互

        常用操作:与sql语言一致,主要是增删改查,接下来就简要概述这4大类

    ******* 增 *******

    session.add(object) #在数据库中增加一个对象实例
    session.add_all([object]) #在数据库中增加多个对象实例,参数为列表形式
    session.commit() #提交,否则未入口
    
    

    ******* 查 *******

    #备注:以下均已object代表对象模型,object.prop代表对象object的prop属性
    session.query(object) #查询object对应的关系表,相当于select * from tables
    session.query(object).first() #查询结果取第一条,没有返回none
    session.query(object).filter(object.prop) #条件查询,filter相当于where
    session.query(object).order_by(object.prop) #排序,默认升序,降序用desc
    session.query(object).order_by(object.prop.desc()).limit(10) #降序,及限制10条
    session.query(object.prop.label("别名")).filter(object.prop.like("%同同mony")) #模糊查询及给字段取别名
    #使用聚合函数,sum、count等
    from sqlalchemy import func
    session.query(func.sum(object.prop).label("别名")
    
    

    ******* 改 *******

    session.query(object).filter(object.prop>20).update({"prop1": 'values'})#批量更新,若没有过滤条件,这更新表中所有记录
    myuser = Session.query(object).filter(object.prop>20).first()
    object.prop2= 'value2' #单条更新,可直接修改对象
    session.commit()
    

    ******* 删 *******

    res = session.query(object).filter(object.prop>20).delete() 
    session.commit()  
    
    

    第二部分

       掌握了基本概念和使用,为了更高效、更快捷将关系表转化成对象,不得不提sqlacodegen工具
    a.安装
        pip install sqlacodegen
    b.使用
      sqlacodegen url [opts]
        这里的url就是sqlalchemy中create_engine使用的参数,但是当账号密码含有特殊字符时,同样的url,在sqlacodegen命令中会报错,识别不出账号、密码、端口等信息,此时可通过给账号和密码加引号解决
        opts:
           --tables TABLES 指定表,默认将所有表转化成对象
           --noindexes 忽略索引
           --noviews 忽略视图
           --noclasses 不生成类,仅生成表
           --outfile OUTFILE 输出文件
    示例:
    sqlacodegen --noviews --noconstraints --noclasses --noindexes --outfile 对应py文件路径 url【同create engine处使用的】
    注意 :当账号和密码包含特殊字符时,需要用引号,否则自动识别不出账号、密码、端口等信息

    示例1:

    #不使用 `--noclasses`导出的对象
    from sqlalchemy import BIGINT, Column, DateTime, Float, String, text
    from sqlalchemy.dialects.mysql.types import TINYINT
    from sqlalchemy.ext.declarative import declarative_base
    
    Base = declarative_base()
    metadata = Base.metadata
    
    class TDeviceActivate(Base):
        __tablename__ = 't_device_activate'
    
        id = Column(BIGINT(10), nullable=False)
        user_id = Column(BIGINT(10), nullable=False)
        device_id = Column(String(32), primary_key=True, nullable=False)
        mac = Column(String(30))
        uuid = Column(String(32))
        firmware_type = Column(String(16), primary_key=True, nullable=False)
        activate_time = Column(DateTime, nullable=False)
        create_date = Column(DateTime, nullable=False)
        ip_address = Column(String(50))
        longitude = Column(Float(10))
        latitude = Column(Float(10))
        expires_time = Column(DateTime)
        type = Column(TINYINT(10), server_default=text("'1'"))
    

    示例2

    #使用 `--noclasses`参数导出的对象
    from sqlalchemy import BIGINT, Column, DateTime, Float, MetaData, String, Table, text
    from sqlalchemy.dialects.mysql.types import TINYINT
    
    metadata = MetaData()
    
    
    t_t_device_activate = Table(
        't_device_activate', metadata,
        Column('id', BIGINT(10), nullable=False),
        Column('user_id', BIGINT(10), nullable=False),
        Column('device_id', String(32), primary_key=True, nullable=False),
        Column('mac', String(30)),
        Column('uuid', String(32)),
        Column('firmware_type', String(16), primary_key=True, nullable=False),
        Column('activate_time', DateTime, nullable=False),
        Column('create_date', DateTime, nullable=False),
        Column('ip_address', String(50)),
        Column('longitude', Float(10)),
        Column('latitude', Float(10)),
        Column('expires_time', DateTime),
        Column('type', TINYINT(10), server_default=text("'1'"))
    )
    

    总结

         在UI回归测试脚本中,通常涉及到与数据库打交道,开始时候主要使用pymysql API 与数据交互,但是随着使用频率的增加,直接书写sql变得繁琐,便尝试使用orm的方式

     


    转载来自:
    作者:小蜗牛的成长
    链接:https://www.jianshu.com/p/84986de8a903
    来源:简书

  • 相关阅读:
    C# Ini配置文件
    C#日志写入
    GZFramework.DB.Core初始化
    httpHelper
    GZFramework代码生成器插件使用教程
    MVC部署IIS设置
    SignalR记录
    洛谷 P2360 地下城主
    洛谷 P1379 八数码难题(map && 双向bfs)
    洛谷 P1155 双栈排序
  • 原文地址:https://www.cnblogs.com/Vera-y/p/11002172.html
Copyright © 2020-2023  润新知