2022年 11月 9日

Python3中tornado高并发框架(5)-MySQL数据库

tornado与数据库mysql交互

概述:tornado 没有自带的ORM,对于数据库需要自己去适配,并且目前python3.6 +tornado还没有比较完善的驱动,PyMySQL支持python3.x,而MySQLdb不支持python3.x

hlx2@NLP:~$ mysql -uroot -p

-p就是-password的意思,然后后面有东西代表密码为空,-u表示-username,后面加了root表示username为root。

mysql>CREATE DATABASE tornado_mysql;

mysql> use tornado_mysql;

 

22.建立连接

1. 用Navicat连接数据库后,简单的创建一个表,
注意:设置主键为id,和自动递增
在这里插入图片描述
注意:新建连接时可能出现:
1130-host … is not allowed to connect to this MySql server错误
解决:https://blog.csdn.net/weixin_43097301/article/details/85892582
1251 Client does not support authenticasider upgrading Mysotocol requested by ser错误
解决:https://blog.csdn.net/weixin_43097301/article/details/85892142

2. 在config中配置数据库
相应的修改为自己的信息

  1. #数据库配置
  2. mysql ={
  3. "host":"192.168.3.36",
  4. "user":"root",
  5. "passwd":"123456",
  6. "dbname":"tornado_mysql"
  7. }
  1. 新建zjMuSQL.py在根目录,即和config同级
  1. import pymysql #导入pymysql,因为PyMySQL支持python3.x,而MySQLdb不支持python3.x
  2. class zjMySQL():
  3. def __init__(self,host,user,passwd,dbName):
  4. self.host = host #登录主机
  5. self.user = user #用户
  6. self.passwd = passwd #密码
  7. self.dbName = dbName #数据库的名,新建的数据库名
  8. def connet(self): #用于连接数据库
  9. self.db=pymysql.connect(self.host,self.user,self.passwd,self.dbName)
  10. self.cursor=self.db.cursor()
  11. def close(self): #用于断开连接
  12. self.cursor.close()
  13. self.db.close()
  14. def get_one(self,sql): #查询一条数据;类型为元组
  15. res=None #sql参数为查询mysql语句
  16. try:
  17. self.connet()
  18. self.cursor.execute(sql) #执行查询
  19. res=self.cursor.fetchone() #获取数据
  20. self.close() #关闭
  21. except:
  22. print("查询失败")
  23. return res
  24. def get_all(self,sql): #获取所有;类型为元组
  25. res = () #sql参数为查询mysql语句
  26. try:
  27. self.connet() #连接数据库
  28. self.cursor.execute(sql) #执行查询语句
  29. res=self.cursor.fetchall() #接收全部的返回结果行
  30. self.close()
  31. except:
  32. print("查询失败")
  33. return res
  34. def get_all_obj(self,sql,tableName,*args): #获取所有;类型为列表
  35. resList = [] #sql:sql查询语句
  36. fieldsList=[]
  37. if(len(args)>0):
  38. for item in args: #遍历字典key
  39. fieldsList.append(item) #添加kry
  40. else:
  41. fieldsSql="select COLUMN_NAME from information_schema.COLUMNS where table_name ='%s'and table_schema = '%s'"%(tableName,self.dbName)
  42. #column name列名 information sheet: 信息表
  43. fields=self.get_all(fieldsSql) #执行语句,获取所有表信息(("id,"),("name",),("age,"))
  44. for item in fields: #遍历key
  45. fieldsList.append(item[0]) #添加
  46. res=self.get_all(sql) #获取传参的查询语句的数据,元组类型tuple
  47. for item in res:
  48. items= item
  49. obj = {}
  50. count = 0
  51. for x in item:
  52. obj[fieldsList[count]]=x
  53. count += 1
  54. resList.append(obj)
  55. return resList
  56. def insert(self,sql): #插入
  57. return self.__edit(sql)
  58. def update(self,sql): #修改
  59. return self.__edit(sql)
  60. def delete(self,sql): #删除
  61. return self.__edit(sql)
  62. def __edit(self,sql):
  63. count = 0
  64. try:
  65. self.connet()
  66. count = self.cursor.execute(sql)
  67. self.db.commit()
  68. self.close()
  69. except:
  70. print("事务提交失败")
  71. self.db.rollback()
  72. return count

4. 在application中最后配置url
省略了路由的handlers=[ ]中的部分代码

注意,路由要放在静态路由((r”/(.*)$”,tornado.web.StaticFileHandler,{“path”:os.path.join(config.BASE_DIRS,“static/html”),“default_filename”:“index.html”}),)之前,不然访问路由会报错

  1. from zjMySQL import zjMySQL
  2. handlers=[
  3. r"/students",index.StudentsHandler),
  4. ]
  5. self.db = zjMySQL(config.mysql["host"],config.mysql["user"],config.mysql["passwd"],config.mysql["dbname"]) #实例化一个ziMySQL的对象db设置连接,访问数据库,方便调用

5. 获取数据

views/index中

  1. class StudentsHandler(RequestHandler): #数据库中获取信息,并展示
  2. def get(self, *args, **kwargs):
  3. # stus = self.application.db.get_all_obj("select name,age from students", "students", "name", "age") #查询指定字段
  4. # 获取数据
  5. stus=self.application.db.get_all_obj("select * from students","students") #查询获取数据
  6. print(stus)
  7. self.write("ok")
  8. # self.render("students.html",stus=stus)

#(pycharm输出):
[{‘id’: 1, ‘name’: ‘小白’, ‘age’: 18}, {‘id’: 2, ‘name’: ‘老王’, ‘age’: 20}]
#表明拿到了数据库的数据

6. 插入数据

views/index中

  1. class StudentsHandler(RequestHandler): #数据库中获取信息,并展示
  2. def get(self, *args, **kwargs):
  3. self.application.db.insert("insert into students (name,age) values('小李',22);") #插入语句
  4. self.write("ok")

 

 

23. 简单的封装一下ORM

在这里插入图片描述

1. 如图新建ORM文件夹

  1. 文件zjMySQL进行了修改
  1. from .zjMysql import zjMySQL
  2. class ORM():
  3. def save(self):
  4. #insert into students(name,age) values ("小李",22)
  5. tableName = (self.__class__.__name__).lower() #表名
  6. #self.__class__获取当前的类;__name__获取当前调用的对象的类名;lower()转小写
  7. fieldsStr =valuesStr="(" #fieldsStr代表(name,age);valuesStr代表("小李",22)
  8. for field in self.__dict__: #self.__dict__得到字典的键值对{"小李":22,"小白":23}中的属性名
  9. fieldsStr += (field + ",") #循环1(name, ;循环2 (name,age,
  10. if isinstance(self.__dict__[field],str): #判断key-valuede中value值是否是字符串
  11. valuesStr += ("'"+self.__dict__[field]+"',")
  12. else: #不是则为数字
  13. valuesStr +=(str(self.__dict__[field])+",") #转为字符串
  14. fieldsStr = fieldsStr[:len(fieldsStr)-1]+")" #截取name (name,age,之前,就把逗号去掉,拼接“)”变成(name,age)
  15. valuesStr = valuesStr[:len(valuesStr)-1]+")" #一样的截取掉后面的逗号,("小李",22)
  16. sql = "insert into " +tableName +" "+ fieldsStr+"values "+valuesStr
  17. db = zjMySQL()
  18. db.insert(sql)
  19. def delete(self):
  20. pass
  21. def update(self):
  22. pass
  23. @classmethod #装饰为类方法,类名来调用
  24. def all(cls):
  25. #select * from students
  26. tableName = (cls.__name__).lower()
  27. sql = "select * from " +tableName
  28. db = zjMySQL()
  29. return db.get_all_obj(sql,tableName)
  30. @classmethod
  31. def filter(cls):
  32. pass

2.文件orm中:只先封装insert和all功能

  1. from .zjMysql import zjMySQL
  2. class ORM():
  3. def save(self):
  4. #insert into students(name,age) values ("小李",22)
  5. tableName = (self.__class__.__name__).lower() #表名
  6. #self.__class__获取当前的类;__name__获取当前调用的对象的类名;lower()转小写
  7. fieldsStr =valuesStr="(" #fieldsStr代表(name,age);valuesStr代表("小李",22)
  8. for field in self.__dict__: #self.__dict__得到字典的键值对{"小李":22,"小白":23}中的属性名
  9. fieldsStr += (field + ",") #循环1(name, ;循环2 (name,age,
  10. if isinstance(self.__dict__[field],str): #判断key-valuede中value值是否是字符串
  11. valuesStr += ("'"+self.__dict__[field]+"',")
  12. else: #不是则为数字
  13. valuesStr +=(str(self.__dict__[field])+",") #转为字符串
  14. fieldsStr = fieldsStr[:len(fieldsStr)-1]+")" #截取name (name,age,之前,就把逗号去掉,拼接“)”变成(name,age)
  15. valuesStr = valuesStr[:len(valuesStr)-1]+")" #一样的截取掉后面的逗号,("小李",22)
  16. sql = "insert into " +tableName +" "+ fieldsStr+"values "+valuesStr
  17. db = zjMySQL()
  18. db.insert(sql)
  19. def delete(self):
  20. pass
  21. def update(self):
  22. pass
  23. @classmethod # 装饰为类方法,类名来调用
  24. def all(cls):
  25. #select * from students
  26. tableName = (cls.__name__).lower()
  27. sql = "select * from " +tableName
  28. db = zjMySQL()
  29. return db.get_all_obj(sql,tableName)
  30. @classmethod
  31. def filter(cls):
  32. pass

3. 新建了models.py,表的属性

  1. from ORM.orm import ORM
  2. class Students(ORM): #继承与ORM
  3. def __init__(self,name,age):
  4. self.name = name
  5. self.age =age

4. views/index中
如果没有路由,相应的配置一下路由
注意,路由要放在静态路由((r”/(.*)$”,tornado.web.StaticFileHandler,{“path”:os.path.join(config.BASE_DIRS,“static/html”),“default_filename”:“index.html”}),)之前,不然访问路由会报错

  1. from models import Students
  2. class StudentsHandler(RequestHandler): #数据库中获取信息,并展示
  3. def get(self, *args, **kwargs):
  4. stu = Students("小黑",24)
  5. stu.save() #存入数据

运行访问http://127.0.0.1:9000/students
进入数据库刷新