Pymysql.err.Error: Already closed

I am trying to create a login function. But it only works. Ex- When I give a wrong user id and password I got the correct error massage that "could not login" after canceling this message and providing the correct user id and password, after which I get "pymysql.err.Error: Already closed" below - sample code.

import pymysql

# Connect to the database
connection = pymysql.connect(host='localhost',
                             user='root',
                             password='',
                             db='python_code',
                             charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor)
class LoginModel:
    def check_user(self, data):

        try:
            with connection.cursor() as cursor:
                # Read a single record
                sql = "SELECT `username` FROM `users` WHERE `username`=%s"
                cursor.execute(sql, (data.username))
                user = cursor.fetchone()
                print(user)

            if user:
                if (user, data.password):
                    return user
                else:
                    return False
            else:
                return False

        finally:
            connection.close()

      

+3


source to share


2 answers


You have a mismatch in relation to the number of times you create the connection (once) and the number of times you close the connection (once per login attempt).

One of the fixes would be moving:

connection = pymysql.connect(host='localhost',
                             user='root',
                             password='',
                             db='python_code',
                             charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor)

      

in def check__user()

. This will work because you will create and close the connection on every call (as others have pointed out, the clause is finally

always executed.)



This is not a great design, because getting database connections tends to be relatively expensive. Therefore, it is preferable to maintain the connection creating outside of the method .... which means you must delete connection.close()

inside the method.

I think you are confusing connection.close()

with cursor.close()

. You want to do the latter, not the former. In your example, you don't need to explicitly close the cursor, because that happens automatically with your string with connection.cursor() as cursor:

.

Change finally

to except

or completely remove the block try

.

+1


source


This is the culprit code:

finally:
    connection.close()

      



In the docs: "A finally clause is always executed before leaving a try statement, whether an exception has occurred or not" From: https://docs.python.org/2/tutorial/errors.html

You have not described alternative behavior for what you would like to see instead, but my answer gets to the heart of your question.

+2


source







All Articles