python ORM framework: SqlAlchemy

  ORM, object-relational mapping, namely Object Relational Mapping short, the mapping relationship with an ORM framework of the relational model programming language, object model and database, aim: to simplify sql language to operate the database of the tedious process (write native sql of and stitching, etc.) in favor of directly using the object model to manipulate the database to make alternative

first part

      SqlAlchemy itself can not directly manipulate the database, it is based on third-party database API (such as pymysql library in python) above, the application calls the object model CRUD operations such as, object transformed into sql statement, and then through the API call execution has been converted to good sql statement

installation

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

application

- Configure and create a database engine

      SqlAlchemy support indirect call multiple database API, API calls according to different databases can not profile

#常见配置文件:即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...] 
- Create a database engine

      * * Note: Bring charset = utf8 parameter, to prevent distortion Chinese

#初始化数据库连接
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执行过程 
- create a session (session)

      By sessionmaker factory method, we get a class, default return Session class, or you can customize Session class
methods:
sessionmaker (the 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对象,此时已绑定数据库引擎,但是未关联任何的对象模型 

VS Session scoped_session
      Session: Session object is created in multiple different
      scoped_session: First Session object is created by sessionmaker factory, then Session object corresponding management (first in the Registry before looking over whether to create a Session, if not, create and registration, there is a direct return), this purpose: to maintain a session with a thread object is to ensure the security thread

- interact with the database

    Common operations: consistent with the sql language, mostly CRUD, then you a brief overview of the four major categories

******* ******* increase

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

******* ******* check

#备注:以下均已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("别名") 

******* ******* change

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

******* ******* deleted

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

the second part

   掌握了基本概念和使用,为了更高效、更快捷将关系表转化成对象,不得不提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
来源:简书

Guess you like

Origin www.cnblogs.com/Vera-y/p/11002172.html