zoukankan      html  css  js  c++  java
  • Python3 从零单排14_flask模块&mysql操作封装

      1.flask模块介绍

      在测试的过程中,往往会遇到功能受接口影响而导致测试无法正常进行,往往要等接口完成之后才能做功能测试,但这往往很托节奏。这个时候就可以考虑,将接口和功能剥离,分开测试,同时进行,保证项目进度。

      问题是怎么分开呢?要研发先帮忙开发接口、调试好,然后测试?显然太low,python这个时候就可以来装一波X,我们自己动手按照需求开发一套接口来供功能测试,其第三方模块flask提供接口服务,早就有大神开发好接口服务的第三方模块,我们直接用就可以了,这就是python的强大之处了,flask模块使用如下:

    import flask  #导入模块
    server=flask.Flask(__name__)  #创建接口服务,格式:flask.Flask(__name__),类似于redis.Redis,其中(__name__)是指当前的python文件,也就是说接口是基于此文档在运行
    @server.route('/api',methods=['get','post'])#创建好接口服务后,需要指定路径,路径包含后缀以及请求方法,必须要是@装饰,下面的函数才能正常运行
    def reg():#接口主体部分,运行内容
        return ('hello world!')
    server.run(port=9999)#服务创建好,并指定好路径,接口内容编写完后,需要启动服务,启动的时候需要指定端口

      上面就是最简洁的接口服务了,运行后就可以访问了,在浏览器输入:http://127.0.0.1:9999/api,浏览器会输出:“hello world!”。但如果想要获取到用户的请求数据、以及局域网内别的测试人员要访问你的接口咋办,代码如下:

    import flask  #导入模块
    from flask import request#导入request方法,用来接收传参
    server=flask.Flask(__name__)  #创建接口服务,格式:flask.Flask(__name__),类似于redis.Redis,其中(__name__)是指当前的python文件,也就是说接口是基于此文档在运行
    @server.route('/login',methods=['get','post'])#创建好接口服务后,需要指定路径,路径包含后缀以及请求方法,必须要是@装饰,下面的函数才能正常运行
    def reg():#接口主体部分,运行内容
        name=request.values.get("username")#request.values.get("username")获取指定传参的value,用来判断、处理
        passwd=request.values.get("password")#如果传参是json类型,方法是request.json.get("username")
        if name and passwd:
            if name.strip() and passwd.strip():
                return '{"code":200,"msg":"注册成功!"}'
        return '{"code":300,"msg":"参数不能为空!"}'
    server.run(port=9999,host='0.0.0.0',debug=True)#指定host为“0.0.0.0”后,局域网内其他IP就都可以访问了

      上述代码基本可以满足接口需求了,然后你可以在接口主体内容内,对传参进行分析、处理,比如得到传参后,与数据库里的数据进行比对、分析,给出正确响应。譬如用户输入用户名和密码,取到参数后,查询数据库中是否存在用户名,且用户名密码是否正确,用来判断是否允许登录。既然如此那么我们要初始化一些数据了,就是在运行接口之前要判断数据库、表以及数据是否存在,不存在则需要初始化创建上述一系列数据,创建数据库的函数如下:

      2.mysql操作函数封装

    def oprate_sql(sql, HOST, USER, PASSWD, charset='utf8', port=3306):#定义操作sql语句的函数,如果是select或show则返回查询内容
        import pymysql
        conn = pymysql.connect(host=HOST, user=USER, password=PASSWD, charset=charset)
        cur = conn.cursor()
        cur.execute(sql)
        if sql.strip().startswith('select') or sql.strip().startswith('show'):
            res = cur.fetchall()
        else:
            conn.commit()
            res = 'ok'
        cur.close()
        conn.close()
        return res
    
    def check_in(args,res):#判断a,是否在res的元素里,这里的res必须是sql执行返回的数据,用于注册,登录
        lis=[]
        for i in res:
            lis.append(i[0])
        if args in lis:
            return True
    #调用:
    sql='show databases;'
    res=oprate_sql(sql, HOST, USER, PASSWD)
    if not check_in(DBNAME, res):
        sql = 'create database %s;' % DBNAME
        oprate_sql(sql, HOST, USER, PASSWD)

      可以看到,在连接数据库的时候不能指定数据库名称,因为不确定是否存在数据库,所以先查询当前数据库存在哪些数据库名,判断是否存在,不存在则建立数据库名,创建表类似。

      但是后面也还要操作数据库,比如增删改查,这些都要指定具体数据库名称才可以,那么久不能用上面的函数了,因为数据库名是必填参数,上述函数并没有,代码如下:

    def oprate_sql(sql, HOST, USER, PASSWD, DBNAME, charset='utf8', port=3306):#定义操作sql语句的函数,如果是select或show则返回查询内容
        import pymysql
        conn = pymysql.connect(host=HOST, user=USER, password=PASSWD, db=DBNAME, charset=charset)
        cur = conn.cursor()
        cur.execute(sql)
        if sql.strip().startswith('select') or sql.strip().startswith('show'):
            res = cur.fetchall()
        else:
            conn.commit()
            res = 'ok'
        cur.close()
        conn.close()
        return res
    #调用:
    sql = 'select username from %s' % (USERTB)
    res=oprate_sql(sql, HOST, USER, PASSWD,DBNAME)

      那么问题来了,怎么合并这两个处理sql的函数呢,还记得我们函数有默认参数吧,我们把DBNAME默认为空字符,调用的时候传了DBNAME,那么我们就连接到具体的数据库名,如果调用的时候没有传DBNAME,那么我们就不连接数据库名,代码如下:

    def oprate_sql(sql, HOST, USER, PASSWD, DBNAME='', charset='utf8', port=3306):#定义操作sql语句的函数,如果是select或show则返回查询内容
        import pymysql
        if DBNAME:
            conn = pymysql.connect(host=HOST, user=USER, password=PASSWD, db=DBNAME, charset=charset)
        else:
            conn = pymysql.connect(host=HOST, user=USER, password=PASSWD, charset=charset)
        cur = conn.cursor()
        cur.execute(sql)
        if sql.strip().startswith('select') or sql.strip().startswith('show'):
            res = cur.fetchall()
        else:
            conn.commit()
            res = 'ok'
        cur.close()
        conn.close()
        return res
    #不传DBNAME
    sql='show databases;'
    res=oprate_sql(sql, HOST, USER, PASSWD)
    #传DBNAME:
    sql = 'select username from %s' % (USERTB)
    res=oprate_sql(sql, HOST, USER, PASSWD,DBNAME=Table_Name)

      3.后面学到了类,可以进一步用类封装mysql操作:

     1 import pymysql
     2 
     3 
     4 class MySql(object):
     5     def __init__(self, host, port, user, pwd, dbname="", charset="utf8"):
     6         """初始化数据库信息以及连接"""
     7         self.host = host
     8         self.port = port
     9         self.user = user
    10         self.pwd = pwd
    11         self.dbname = dbname
    12         self.charset = charset
    13         self.conn = None  # 给析构函数用的,如果存在链接,则需要关闭链接,没有就不用管
    14         self.conn = self.get_conn
    15         self.cur = None
    16         self.cur = self.get_cur
    17 
    18     @property
    19     def get_conn(self):
    20         """根据传参判断是否有传数据库名,然后做不同的链接操作"""
    21         try:
    22             if self.dbname:
    23                 conn = pymysql.connect(host=self.host, port=self.port, user=self.user,
    24                                             password=self.pwd, database=self.dbname, charset=self.charset)
    25                 return conn
    26             else:
    27                 conn = pymysql.connect(host=self.host, port=self.port, user=self.user,
    28                                             password=self.pwd, charset=self.charset)
    29                 return conn
    30         except Exception as e:
    31             print(e)
    32 
    33     @property
    34     def get_cur(self):
    35         """获取游标"""
    36         if self.conn:
    37             return self.conn.cursor()
    38 
    39     def exec_sql(self, sql, *args):
    40         """
    41         执行sql,根据不同的sql语法做不同的操作:
    42         查询就返回查询结果列表,其他成功就返回受影响的行数整型,报错返回报错信息字符串
    43         *args是为了防止sql注入,自己拼接的sql语法字符串可能被sql注入,
    44         这里的用法是sql不需要自己拼接,直接将变量按顺序传进来,pymysql自动拼接,而且避免了sql注入的问题
    45         如:
    46         sql = "insert into test.student VALUES (19,%s,'English',%s);"
    47         res = test_mysql.exec_sql(sql,"yangxga",100)
    48         """
    49         try:
    50             rows = self.cur.execute(sql, args)  # rows记录受影响的行
    51             if sql.strip().startswith('select') or sql.strip().startswith('show'):
    52                 res = self.cur.fetchall()
    53                 res = self.format_res(res)
    54                 return res
    55             else:
    56                 self.conn.commit()  # 非查询语句需要提交才能生效
    57                 res = rows
    58                 return res
    59         except Exception as e:
    60             return e
    61 
    62     @staticmethod
    63     def format_res(res):
    64         """格式化数据库查找到的结果,如果"""
    65         res_lis = []
    66         if res:
    67             for i in res:
    68                 res_lis.append(i)
    69         return res_lis
    70 
    71     def __del__(self):
    72         """析构函数,关闭鼠标,断开连接"""
    73         if self.cur:
    74             self.cur.close()
    75         if self.conn:
    76             self.conn.close()
  • 相关阅读:
    用户自定义异常
    触发异常
    第一阶段冲刺终
    第一阶段冲刺七
    第一阶段冲刺六
    第一阶段冲刺五
    第一阶段冲刺四
    Sufficient Statistic (充分统计量)
    DAG-GNN: DAG Structure Learning with Graph Neural Networks
    Masked Gradient-Based Causal Structure Learning
  • 原文地址:https://www.cnblogs.com/znyyy/p/10072938.html
Copyright © 2011-2022 走看看