'NoneType' object has no attribute 'cursor'
Asked Answered
D

4

10

I have created a very simple web app using Flask and I have a MySQL database connected. FYI, I am using bash on windows.

The below function registers a person into the Mysql Database and it works as expected. The cursor object is defined and data are saved into MySQL.

@app.route('/register', methods=['GET','POST'])
def register():
    form = RegisterForm(request.form)
    if request.method == 'POST' and form.validate():
        name = form.name.data
        email = form.email.data
        username = form.username.data
        password = hash.encrypt(str(form.password.data))

        # Create cursor
        cur = mysql.connection.cursor()
        cur.execute("INSERT INTO users(name, email, username, password) VALUES(%s, %s, %s, %s)",
        [name, email, username, password])

        # commit to db
        mysql.connection.commit()

        # close connection
        cur.close()

        flash('You are now registered and can log in', 'success')

        return redirect(url_for('login'))

    return render_template('register.html', form=form)

The problem starts when I want to load data from mysql:

def data():
    cur = mysql.connection.cursor()
    cur.execute("SELECT * FROM users")
    mysql.connection.commit()
    cur.close()

data()

I get the error:

File "app.py", line 23, in data cur = mysql.connection.cursor() AttributeError: 'NoneType' object has no attribute 'cursor'

As pointed out by @Martijn Pieters, this means that I could not connect to the mysql database. The question is, why does flask connect without a problem in the first function and has issues with the second function?

Below are my imports for replication:

from flask import Flask, render_template, flash, request, redirect, url_for, session, logging, url_for
from data import Articles
from flask_mysqldb import MySQL
from wtforms import Form, StringField, TextAreaField, PasswordField, validators
from passlib.hash import sha256_crypt

app = Flask(__name__)

#init MYSQL
mysql=MySQL(app)
Doxy answered 12/10, 2018 at 12:54 Comment(1)
I also experienced this. It seems this is a problem only if 2 functions are not in the same file? when multiple functions are in the same file it seems fine to me.Darladarlan
T
22

The error occurs because mysql.connection is None. It doesn't matter here what type of object mysql is.

The Flask-MySQL documentation for MySQL.connection tells you when that attribute is going to be None:

Attempts to connect to the MySQL server.

Returns: Bound MySQL connection object if successful or None if unsuccessful.

So the attempt to connect to the server could have failed. The extension will open a connection to MySQL once per request; it failed to connect on a separate request from the one that succeeded.

Looking at the source code for the extension I see that it'll also return None when there is no app context (at which point _app_ctx_stack.top is None). You can't use this function outside of a request.

If you do need this outside of a request, you need to manually create an app context first:

with app.app_context():
    cur = mysql.connection.cursor()
Tacita answered 12/10, 2018 at 13:7 Comment(4)
@Toutsos: I note that creating a new connection for every request is hardly efficient. You may want to look at Flask-SQLAlchemy instead for a more robust solution (that'll make use of a connection pool to re-use existing connections, which are kept open for longer). Not that that'll solve your 'no app context' issue.Tacita
It's taken me several hours just to find this, I couldn't for the life of me figure out why it wasn't working. Returning None if there's no app context without any warning is terribleIntersexual
Check https://mcmap.net/q/1162113/-sql-server-merge-statement-in-python it worked for me.Endosteum
@DrPotato: that has nothing to do with this extension, that answer applies to SQLAlchemy, not Flask-MySQL.Tacita
D
0

These errors occur when your DB connection is not established. So please check your DB connection method and properties and then try to execute.

Dailey answered 12/5, 2021 at 14:12 Comment(0)
C
0

if You are making your environment in conda in might give an error instead

  1. pip install virtualenv
  2. virtualenv testing45
  3. .\env\Scripts\activate{in Windows}
  4. pip install flask
  5. pip install flask_mysqldb

It will work

Caenogenesis answered 5/3, 2024 at 5:19 Comment(0)
B
-1

These Error may be occur due to you connection file. for example:

import sqlite3

def db_connection():
    conn = None
    try:
        conn = sqlite3.connect("path_of_db/db_name.sqlite")
    except sqlite3.Error as e:
        print(e)
    return conn

If path is missing or due to wrong path you will face similar Error.

Brawl answered 28/8, 2022 at 11:34 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.