zoukankan      html  css  js  c++  java
  • 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
    来源:简书

  • 相关阅读:
    1451. Rearrange Words in a Sentence
    1450. Number of Students Doing Homework at a Given Time
    1452. People Whose List of Favorite Companies Is Not a Subset of Another List
    1447. Simplified Fractions
    1446. Consecutive Characters
    1448. Count Good Nodes in Binary Tree
    709. To Lower Case
    211. Add and Search Word
    918. Maximum Sum Circular Subarray
    lua 时间戳和时间互转
  • 原文地址:https://www.cnblogs.com/Vera-y/p/11002172.html
Copyright © 2011-2022 走看看