为什么fetchall总是导致“无”?

2024-05-16 09:40:03 发布

您现在位置:Python中文网/ 问答频道 /正文

以下是MySQL数据库中的数据:

python3表:用户信息

enter image description here

但是当我使用fetchall获取表中的所有数据时,它总是返回none

enter image description here

我真的真的不知道怎么解决它,会有人遇到这个问题吗

以下是代码文件

封装.py

import MySQLdb

class mysql_encapsulation(object):
    def __init__(self,host,port,user,passwd,db,charset):
        self.host = host
        self.port = port
        self.user = user
        self.passwd = passwd
        self.db = db
        self.charset = charset

    def open(self):
        self.conn = MySQLdb.connect(host=self.host,port=self.port,user=self.user,passwd=self.passwd,db=self.db,charset=self.charset)
        self.cursor = self.conn.cursor()

    def close(self):
        self.cursor.close()
        self.conn.close()

    def operate(self,sql,params):
        try:
            self.open()
            self.cursor.execute(sql,params)
            self.conn.commit()
            print(' operate ok')
            self.close()
        except Exception,e:
            print(e.message)
            self.conn.rollback()

    def get_result_set(self,sql,params=[]):
        result=None
        try:

            self.open()
            self.cursor.execute(sql,params)
            result = self.cursor.fetchall()
            self.close()


        except Exception,e:
            print('error!')
            print(e.message)

        return result

使用.py(此文件中存在问题)

#coding=utf-8
from encapsulation import *

mysql = mysql_encapsulation(port=3306,host='localhost',user='root',passwd='mysql',
                           db='python3',charset='utf8')

sql='select id,name from users_info where id=3'
result=mysql.get_result_set(sql)
print (result)

Tags: selfhostclosedbsqlportdefmysql
3条回答

这种方法存在问题

def get_result_set(self,sql,params=[]):
    result=None
    try:
        self.open()
        self.cursor.execute(sql,params)
        result = self.cursor.fetchall()
        self.close()
    except Exception,e:
        print('error!')
        print(e.message)
    return result

try块(self.open / self.cursor.exec / result = self.cursor.fetch)中前3行中的一行生成了一个错误,然后您将在except块中捕获该错误(您可以看到它打印“error!”)。这就是为什么result始终保持在它的默认None值中的原因。删除except块,它将告诉您发生了什么类型的错误

您几乎永远都不应该捕获最简单的Exception,而是应该捕获特定类型的异常并正确地处理它们,这个问题就是一个很好的例子

出现问题的错误可能是因为在SQL查询中选择了idname,而表中的列实际上是iduser_name。所以您的SQL查询应该是这样的

sql = 'select id, user_name from users_info where id = 3'

正如ruohola在回答中已经解释的那样,您的异常处理程序正在隐藏所有关于真正出了什么问题的重要信息-FWIW,在屏幕截图中None上方打印了“Error!”字符串。关键是:您的try/except块不仅没有用处,实际上是有害的——它阻止了调用堆栈中的其他一些代码甚至意识到出现了问题(并最终解决了问题),它还阻止知道出了什么问题。作为一般规则,只捕获您期望的异常,并在代码中的这一点上有效地处理该异常-如果此时无法修复错误,请让异常传播并让调用代码处理它。此外,您希望在try子句中包含尽可能少的代码(当然,唯一的异常是应用程序的顶级异常处理程序)

话虽如此,想要得到异常警告确实有一个非常合理的理由,那就是确保释放资源(并最终回滚事务),但是您希望1/使用finally子句进行资源清理(无论发生什么情况,finally块总是执行,2/用于回滚部分,使用except子句,但重新引发异常,即:

# leave this one out of the try block - 
# there's nothing you can do here about a connection error
# so let the calling code deal with it
self.connect()

try:
    self.cursor.execute(sql, params)
except Exception as e:
    self.connection.rollback()
finally:
    # this will ALWAYS be executed (unless `self.connect()` raised
    # but then you don't even want to close the connection <g>
    self.close()

你的问题的真正原因,Kurose的答案肯定是正确的

此外,您的“mysql_封装”类(the naming)还有许多其他问题值得商榷,但让我们忽略这个ATM),主要的问题是打开和关闭每个查询的连接。打开数据库连接的成本相当高,因此您希望尽可能长时间地保持它的打开状态(如果出现“2006 mysql已消失”错误,则最终重新连接)

你检查过你的sql语句了吗?根据您的表,您的列是“id”、“user_name”和“passwd”,但在您的sql中,您正在搜索“id”和“name”,而“name”不是列,因此将抛出错误。将sql更改为“sql='select id,user\u name from users\u info where id=3'”

相关问题 更多 >