在django中执行自定义语句的时候,返回的结果是一个tuple ,并我不是我所期望的dict.
当结果是tuple 时,如果要取得数据,必须知道对应数据在结果集中的序号,用序号的方式去得到值。
如果是python与mysql 或pgsql方式,这种方式可以得到dict结果:
mysql:
import pymysql
def connectMysql(self):
"""
Mysql数据库连接
"""
for _ in range(10):
try:
conn = pymysql.connect(**self.base_info)
# 返回字典格式的数据
cursor = conn.cursor(pymysql.cursors.DictCursor)
return conn, cursor
except Exception as err:
logger.exception("数据库连接失败, %s" % err)
return None, None
postgresql:
import psycopg2
import psycopg2.extras
def connectPostgreSQL(self):
"""
PG库连接
"""
for _ in range(10):
try:
conn = psycopg2.connect(**self.base_info)
cursor = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
return conn, cursor
except Exception as err:
logger.exception("数据库连接失败, %s" % err)
return None, None
而在django中,用类似的方法测试:
from django.db import connection
import MySQLdb
.......
cursor = connection.cursor(cursorclass = MySQLdb.cursors.DictCursor)
cursor.execute(sql,None)
结果报错,没有cursorclass 这个参数,说明 django 在封装的时候,没有这个选项。
既然没有这个选项,就只能自己去实现了,根据cursor中的 description 得到各查询的字段名,然后再根据得到的结果,把这两个拼凑起来得到结果。
封装:
from django.db import connection
try:
with connection.cursor() as cursor:
cursor.execute(sql)
# 获取字段名称
col_names = [desc[0] for desc in cursor.description]
results = cursor.fetchall()
rows = []
for result in results:
row = dict(zip(col_names, result))
rows.append(row)
cursor.execute(sql_total)
total = cursor.fetchall()
connection.commit()
except Exception as e:
logger.error(e)
logger.error(sql)
总结:如果用 django 不是复杂的SQL 查询,尽量用 orm 去完成。如果是比较复杂的SQL语句,涉及到很多表,而且并不完全满足django 的foregion key ,甚至是多个 primary key 对应的话,就自己用 原生的SQL 去完成。可能会更好,但在生成字典的时候,数据量不要太大,没测试过太大会有什么性能问题。但对于小数据量,肯定没问题,基本不用考虑性能。