python数据库:以字典形式返回
python数据库:以字典形式返回

python数据库:以字典形式返回

在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 去完成。可能会更好,但在生成字典的时候,数据量不要太大,没测试过太大会有什么性能问题。但对于小数据量,肯定没问题,基本不用考虑性能。

发表回复

您的电子邮箱地址不会被公开。