Django执行原生SQL语句
前言
一般,使用django读写数据都是通过Model,如Model.objects.filter(条件),它需要遵循django的对象关系映射(Object Relational Mapping,简称ORM),且Model.objects.filter()返回的是List列表,形式如data中数据:
{
"data": [
{
"model": "myapp.user",
"pk": 1,
"fields": {
"user_code": "123456789",
"password": "111111111",
"user_role": "admin",
"user_mail": null,
"user_name": null,
"add_time": "2020-10-12T16:33:16Z"
}
}
],
"msg": "show successfully",
"error_tag": 0
}
如何在django中执行原生的SQL语句?
用 connection库 和原生的SQL语句读数据库,如下:
from django.db import connection # 导入connection
sql_str = "select * from book" # str类型的原生sql语句
cursor = connection.cursor() # 用建立好的connection对象创建cursor游标对象
cursor.execute(sql_str) # 执行自定义SQL语句
dataInfo = cursor.fetchall() # 取出执行返回的记录,返回的tuple类型数据
cursor.close()# 执行完,关闭
connection.close()
上述操作可写成:
from django.db import connection
sql_str = "select * from book"
with connection.cursor() as cursor # with语句用于数据库操作
cursor.execute(sql_str)
dataInfo = cursor.fetchall()
用 connection库 和原生的SQL语句写数据库时,要注意:
1、connection.commit() # 增删改操作要提交事务给connection对象,它改变了数据库值。
2、pymysql中可以设置游标为字典类型,django中不行,需要自行封装
cusor是什么?
游标(cursor)是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果,主要用于处理和接收数据,可方便的对数据库进行增、删、改、查等各种操作。
获取字典类型的结果
django中Model.objects.filter()返回的是List,而SQL执行后返回的是Tuple,且django中不像pymsql可以直接指定cursor的类型,因此,我们自行要封装,使返回的类型保持一致,具体如下:
def dict_fetchall(cursor): # cursor是执行sql_str后的记录,作入参
columns = [col[0] for col in cursor.description] # 得到域的名字col[0],组成List
return [
dict(zip(columns, row)) for row in cursor.fetchall() #
]
zip(columns,row) # 把列表columns和元组row两两对应组合,返回的是tuple数据
dict(zip(columns,row)) # 把tuple转成dict键值对,返回的generator对象
[dict(zip(columns, row)) for row in cursor.fetchall()] # 转成List
>> dict(zip(元组1,元组2,元组3)) # 三个参数会报错如下
>> ValueError: dictionary update sequence element 0 has length 3; 2 is required
with connection.cursor() as cursor:
cursor.execute(sql)
dataInfo = dict_fetchall(cursor) # 调用上面的dict_fetchall()方法
return dataInfo
最后dataInfo返回的数据形式如data:
{
"data": [
{
"id": 7,
"asset_num": "A20187453",
"owner_num": "张三",
},
{
"id": 8,
"asset_num": "A20171523",
"owner_num": "李四",
},
{
"id": 9,
"asset_num": "A25001786",
"owner_num": "王五",
}
]
"msg": "show successfully",
"error_tag": 0
}
参考文档
django中使用原生sql操作 https://zhidao.baidu.com/question/558043368657539172.html
第三方库之django.db的connection库 https://blog.csdn.net/wenph2008/article/details/41721511
pymsql中执行sql语句:https://blog.csdn.net/Thousa_Ho/article/details/69525215
自行封装执行结果:https://www.cnblogs.com/juices/p/14660749.html