搭建Tornado Https服务器之Tornado连接MySql数据库(4-2增删改查)

    在上一篇文章中我们已经准备好了两张表users和classes,同时我们还在classes中插入了一条记录,并且我们建了一个工程文件,那么接下来在上一篇的基础上,我们开始写对users表的相关操作。

一、写一个全局父类

       上一篇文章中我们提到,需要为请求设置允许跨域,需要option函数,同时还发现连接函数也是共性,那么为了简化代码,我们不妨写一个父类,包含这些方法,其他的请求类继承此父类.

1、我们再handler目录下新建basehandler.py文件,并在里面写下如下代码:

import tornado.web # 导入tornado模块

# 这是一个父类,此父类允许跨域,并对预请求做了处理
class BaseHandler(tornado.web.RequestHandler):
    """
    基本数据配置
    """
    # 连接数据库参数,需要替换
    connect={
        'host' : 'x.x.x.x', 
        'port' : 3306, 
        'user' : 'root', 
        'passwd' : 'root', 
        'db' : 'test'
    }
    # 配置请求头,允许跨域,否者在浏览器调用的时候报错误
    def set_default_headers(self):
        self.set_header("Access-Control-Allow-Origin", "*")
        self.set_header("Access-Control-Allow-Headers", "Content-Type")
        self.set_header("Access-Control-Allow-Methods", "POST,GET,OPTIONS")

    # 这个函数是必要的,有些浏览器或者测试工具在访问之前都会预先访问,你不写的话会导致出错的
    def options(self):
        self.finish()

2、下面我们更新classhandler.py文件代码:

重点说明一下 **是解包的意思 可以将字典解开,把键值对一一取出

from basehandler import BaseHandler
import pymysql #导入连接mysql的驱动模块

# 这是一个处理新建班级的请求类,继承tornado.web.RequestHandler
class NewClassHandler(BaseHandler):
    # 重写post请求函数,处理post请求
    def post(self):
        # 为了防止出错导致程序崩溃,我们需要捕获异常函数,并处理 
        try:
            # 从请求中获取参数,如果获取不到,我们赋值 None
            classname = self.get_argument('classname', None)
            # 对传入的参数进行判断,如果为空我们回复 error,并终止执行下去
            if not classname:
                # self.write()函数的参数为标准的json类型
                self.write({"error":"班级名称为空!"})
                return
            # 如果不为空那么开始访问数据库吧
            # 首先是sql语句
            sql = "insert into classes(classname) values('{0}')".format(classname)
            # 创建连接对象,相应的参数 意思依次为 主机ip 端口 数据库用户名 数据库用户密码 数据库名称
            # **是解包字典
            conn = pymysql.connect(**BaseHandler.connect)
            # 创建连接游标,用于读写数据库
            cursor = conn.cursor()
            # 执行sql语句,并返回影响行数
            effect_row = cursor.execute(sql)
            # 提交数据
            conn.commit()
            # 关闭游标和连接
            cursor.close()
            conn.close()
            # 插入成功 那么影响函数是1
            if effect_row>0:
                self.write({"success":"插入班级信息成功"})
            else:
                self.write({"error":"插入班级信息失败"})
        except Exception as e:
            # 如果出现异常我们打印出来
            print(e)
            self.write({"error":"服务器出错!"})

二、接下来就是写userhandler.py文件了:

from basehandler import BaseHandler
import pymysql #导入连接mysql的驱动模块

# 这是一个处理新建用户的请求类,继承BaseHandler
class NewUserHandler(BaseHandler):
    # 重写post请求函数,处理post请求
    def post(self):
        # 为了防止出错导致程序崩溃,我们需要捕获异常函数,并处理 
        try:
            # 从请求中获取参数,如果获取不到,我们赋值 None
            username = self.get_argument('username', None)
            password = self.get_argument('password', None)
            class_id = self.get_argument('class_id', None)
            # 对传入的参数进行判断,如果为空我们回复 error,并终止执行下去
            if not username:
                # self.write()函数的参数为标准的json类型
                self.write({"error":"用户账号为空!"})
                return
            if not password:
                # self.write()函数的参数为标准的json类型
                self.write({"error":"用户密码为空!"})
                return
            if not class_id:
                # self.write()函数的参数为标准的json类型
                self.write({"error":"班级没有选择!"})
                return
            # 如果不为空那么开始访问数据库吧
            # 首先是sql语句
            sql = "insert into users(username,password,class_id) values('{0}','{1}',{2})".format(username,password,class_id)
            # 创建连接对象,相应的参数 意思依次为 主机ip 端口 数据库用户名 数据库用户密码 数据库名称
            conn = pymysql.connect(**BaseHandler.connect)
            # 创建连接游标,用于读写数据库
            cursor = conn.cursor()
            # 执行sql语句,并返回影响行数
            effect_row = cursor.execute(sql)
            # 提交数据
            conn.commit()
            # 关闭游标和连接
            cursor.close()
            conn.close()
            # 插入成功 那么影响函数是1
            if effect_row>0:
                self.write({"success":"插入用户信息成功"})
            else:
                self.write({"error":"插入用户信息失败"})
        except Exception as e:
            # 如果出现异常我们打印出来
            print(e)
            self.write({"error":"服务器出错!"})

# 这是一个处理获取用户信息的请求类,继承BaseHandler
class GetUserHandler(BaseHandler):
    # 重写get请求函数,处理get请求
    def get(self):
        # 为了防止出错导致程序崩溃,我们需要捕获异常函数,并处理 
        try:
            # 从请求中获取参数,如果获取不到,我们赋值 None
            user_id = self.get_argument('id', None)
            # 对传入的参数进行判断,如果为空我们回复 error,并终止执行下去
            if not user_id:
                # self.write()函数的参数为标准的json类型
                self.write({"error":"用户id为空!"})
                return
            # 如果不为空那么开始访问数据库吧
            # 首先是sql语句,我们获取用户信息当然希望获取到班级信息啦,密码也不需要啊,因此联合查询指定查询字段走起
            # 被忘记指定字段属主哦 不然 歧义报错
            sql = "select users.id,username,users.createtime,classname from users join classes on classes.id=class_id where users.id={0}".format(user_id)
            # 创建连接对象
            conn = pymysql.connect(**BaseHandler.connect)
            # 创建连接游标,用于读写数据库
            cursor = conn.cursor()
            # 执行sql语句,并返回影响行数
            effect_row = cursor.execute(sql)
            # 通过游标返回一行数据
            user = cursor.fetchone()
            # 关闭游标和连接
            cursor.close()
            conn.close()
            # 返回的数据是元组,我们需要包装一下
            user_dir={}
            if user:
                user_dir["id"]=user[0]
                user_dir["username"]=user[1]
                # createtime是timestamp类型,需要转换成字符串型的
                user_dir["createtime"]=user[2].strftime('%Y-%m-%d %H:%M:%S')
                user_dir["classname"]=user[3]
            self.write({"success":user_dir})
        except Exception as e:
            # 如果出现异常我们打印出来
            print(e)
            self.write({"error":"服务器出错!"})

# 这是一个处理获取用户列表的请求类,继承BaseHandler
class ListUserHandler(BaseHandler):
    # 重写get请求函数,处理get请求
    def get(self):
        # 为了防止出错导致程序崩溃,我们需要捕获异常函数,并处理 
        try:
            # 首先是sql语句,我们获取用户信息当然希望获取到班级信息啦,密码也不需要啊,因此联合查询指定查询字段走起
            # 被忘记指定字段属主哦 不然 歧义报错
            sql = "select users.id,username,users.createtime,classname from users join classes on classes.id=class_id"
            # 创建连接对象
            conn = pymysql.connect(**BaseHandler.connect)
            # 创建连接游标,用于读写数据库
            cursor = conn.cursor()
            # 执行sql语句,并返回影响行数
            effect_row = cursor.execute(sql)
            # 通过游标返回一行数据
            users = cursor.fetchall()
            # 关闭游标和连接
            cursor.close()
            conn.close()
            user_list=[]
            # 返回的数据是元组列表,我们需要包装一下
            for user in users:
                user_dir={}
                user_dir["id"]=user[0]
                user_dir["username"]=user[1]
                # createtime是timestamp类型,需要转换成字符串型的
                user_dir["createtime"]=user[2].strftime('%Y-%m-%d %H:%M:%S')
                user_dir["classname"]=user[3]
                user_list.append(user_dir)
            self.write({"success":user_list})
        except Exception as e:
            # 如果出现异常我们打印出来
            print(e)
            self.write({"error":"服务器出错!"})

# 这是一个处理更改用户信息的请求类,继承BaseHandler
# 这里我们只更改密码,如果你有想法的可以自己增加
class UpdateUserHandler(BaseHandler):
    # 重写post请求函数,处理post请求
    def post(self):
        # 为了防止出错导致程序崩溃,我们需要捕获异常函数,并处理 
        try:
            # 从请求中获取参数,如果获取不到,我们赋值 None
            user_id = self.get_argument('id', None)
            password = self.get_argument('password', None)
            # 对传入的参数进行判断,如果为空我们回复 error,并终止执行下去
            if not user_id:
                # self.write()函数的参数为标准的json类型
                self.write({"error":"用户账号为空!"})
                return
            if not password:
                # self.write()函数的参数为标准的json类型
                self.write({"error":"用户密码为空!"})
                return
            # 如果不为空那么开始访问数据库吧
            # 首先是sql语句,因为password是字符串类型 我们一般会加上单引号,防止报错
            sql = "update users set password='{1}' where id={0}".format(user_id,password)
            # 创建连接对象
            conn = pymysql.connect(**BaseHandler.connect)
            # 创建连接游标,用于读写数据库
            cursor = conn.cursor()
            # 执行sql语句,并返回影响行数
            effect_row = cursor.execute(sql)
            # 提交数据
            conn.commit()
            # 关闭游标和连接
            cursor.close()
            conn.close()
            # 需要注意的是,如果我们密码没有改变而更新的话,影响的行数其实是不变的
            if effect_row>0:
                self.write({"success":"更新用户信息成功!"})
            else:
                self.write({"error":"更新用户信息失败!,可能前后更改数据一致。"})
        except Exception as e:
            # 如果出现异常我们打印出来
            print(e)
            self.write({"error":"服务器出错!"})

# 这是一个处理删除用户信息的请求类,继承BaseHandler
class DeleteUserHandler(BaseHandler):
    # 重写get请求函数,处理get请求
    def get(self):
        # 为了防止出错导致程序崩溃,我们需要捕获异常函数,并处理 
        try:
            # 从请求中获取参数,如果获取不到,我们赋值 None
            user_id = self.get_argument('id', None)
            # 对传入的参数进行判断,如果为空我们回复 error,并终止执行下去
            if not user_id:
                # self.write()函数的参数为标准的json类型
                self.write({"error":"用户账号为空!"})
                return
            # 如果不为空那么开始访问数据库吧
            sql = "delete from users where id={0}".format(user_id)
            # 创建连接对象
            conn = pymysql.connect(**BaseHandler.connect)
            # 创建连接游标,用于读写数据库
            cursor = conn.cursor()
            # 执行sql语句,并返回影响行数
            effect_row = cursor.execute(sql)
            # 提交数据
            conn.commit()
            # 关闭游标和连接
            cursor.close()
            conn.close()
            # 需要注意的是,如果我们密码没有改变而更新的话,影响的行数其实是不变的
            if effect_row>0:
                self.write({"success":"删除用户信息成功!"})
            else:
                self.write({"error":"删除用户信息失败!"})
        except Exception as e:
            # 如果出现异常我们打印出来
            print(e)
            self.write({"error":"服务器出错!"})

需要更新main.py文件,添加更多的路由

import sys
# 将handler目录下的文件放到和main.py文件同级目录下,便于我们引用
sys.path.append("./handler")
# 添加必要的tornado的模块
import tornado.ioloop
import tornado.web
# 从classhandler.py文件中导出写好的 类
from classhandler import NewClassHandler
from userhandler import NewUserHandler,GetUserHandler,ListUserHandler,UpdateUserHandler,DeleteUserHandler

# 写程序入口函数 main函数
def main():
    # 定义请求的路径和响应的请求类,此类会根据你发出的请求区分get 还是post而给予不同的处理
    application = tornado.web.Application([
        (r"/class/new", NewClassHandler),
        (r"/user/new", NewUserHandler),
        (r"/user/info", GetUserHandler),
        (r"/user/list", ListUserHandler),
        (r"/user/update", UpdateUserHandler),
        (r"/user/delete", DeleteUserHandler),
        ])
    # 绑定端口,单进程启动
    application.listen(8000)
    tornado.ioloop.IOLoop.instance().start()

if __name__ == "__main__":
    main()

三、接下来我们测试一下

执行main.py文件

1、插入用户,我们插入两个,因为删除和获取列表需要

2、根据id更改用户密码

3、根据id查看用户信息 

4、获取用户列表

 

 

5、删除用户

 

我们看一下数据库

到此我们已经结束对mysql的简单学习,下一章我们将要尝试连接postgresql数据库。 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江湖人称王某人的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值