Forums

Randomly losing connection to MySQL

(2013, 'Lost connection to MySQL server during query')

My site is in development and i am the only user. I non-stop get this error when using the site. It happens about 25% of the queries. On some refreshes the data does not load, sometimes it's the CSS that does not load, but mostly the entire site gets a server issue until i refresh a couple of times. I've been dealing with this for weeks and I need to get it fixed. The problem goes away if i switch to sqlite, but comes right back with mysql. I'm the only user

How do you manage the db connection in your code?

Below are my models and database reference from the flask app. Thank you in advance for your help

app.py

app.config['SECRET_KEY'] = 'removed'
 app.config['SECURITY_PASSWORD_SALT'] = 'removed'
 app.config['SECURITY_REGISTERABLE'] = True 
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://removed:removed@removed.mysql.pythonanywhere-services.com/removed$user'

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False


user_datastore = SQLAlchemyUserDatastore(db, User, Role) 
 security = Security(app, user_datastore)


 init_db(app)

models.py

from flask_sqlalchemy import SQLAlchemy 
from flask_security import UserMixin, RoleMixin 
from flask_migrate import Migrate

db = SQLAlchemy()

roles_users = db.Table('roles_users', 
 db.Column('user_id', db.Integer(), db.ForeignKey('user.id')), 
 db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))

class Role(db.Model, RoleMixin): 
 id = db.Column(db.Integer(), primary_key=True) 
 name = db.Column(db.String(80), unique=True) 
 description = db.Column(db.String(255))

class User(db.Model, UserMixin): 
 id = db.Column(db.Integer, primary_key=True) 
 email = db.Column(db.String(255), unique=True) 
 password = db.Column(db.String(255)) 
 active = db.Column(db.Boolean()) 
 confirmed_at = db.Column(db.DateTime()) 
 roles = db.relationship('Role', secondary=roles_users, backref=db.backref('users', lazy='dynamic')) 
 fs_uniquifier = db.Column(db.String(255), unique=True, nullable=False)


category_word_table = db.Table('category_word', 
 db.Column('word_id', db.Integer, db.ForeignKey('dictionary.id'), primary_key=True), 
 db.Column('category_id', db.Integer, db.ForeignKey('category.id'), primary_key=True))

class Category(db.Model): 
 id = db.Column(db.Integer, primary_key=True) 
 name = db.Column(db.String(100), nullable=False, unique=True) 
 words = db.relationship('Dictionary', secondary=category_word_table, backref='categories')

class Dictionary(db.Model): 
 id = db.Column(db.Integer, primary_key=True) 
 word = db.Column(db.String(255)) 
 definition = db.Column(db.Text)


class UserInteraction(db.Model): 
 id = db.Column(db.Integer, primary_key=True) 
 user_id = db.Column(db.Integer, db.ForeignKey('user.id')) 
 word_id = db.Column(db.Integer, db.ForeignKey('dictionary.id')) 
 transcribed_word = db.Column(db.String(255)) 
 is_correct = db.Column(db.Boolean)

 user = db.relationship('User', backref=db.backref('interactions', lazy='dynamic')) 
 word = db.relationship('Dictionary', backref=db.backref('interactions', lazy='dynamic'))


def init_db(app): 
 db.init_app(app) 
 Migrate(app, db) 
 with app.app_context(): 
     db.create_all()

I think that the problem is that you're not passing your app object in when you create the SQLAlchemy object in models.py -- it should be

db = SQLAlchemy(app)

You may have to restructure your code in order to do that, of course, because the app object is only available in app.py and you want to use it in models.py. There are a lot of good resources on how to structure a Flask site in order to do that on the web -- if you google for it, you'll find a good tutorial that will explain how to set things up.

I went ahead and moved the models back to the main app file so I could isolate the issue. Below is what i am working with.

I'm still getting sporadic constant drops (MySQLdb.OperationalError: (2013, 'Lost connection to MySQL server during query')).

The problem goes away if i use sqlite, but i want mysql to work. Thanks again for your help.

app.py

from flask import Flask
import os
from flask_sqlalchemy import SQLAlchemy
from flask_security import Security, SQLAlchemyUserDatastore, UserMixin, RoleMixin
from flask_mail import Mail
from flask_migrate import Migrate

os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = 'removed'

app = Flask(__name__, static_url_path='/static')

# Configs
app.config['SECRET_KEY'] = 'removed'
app.config['SECURITY_PASSWORD_SALT'] = 'removed'
app.config['SECURITY_REGISTERABLE'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://removed:removed@removed.mysql.pythonanywhere-services.com/removed$user'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['MAIL_SERVER'] = 'smtp.gmail.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USERNAME'] = 'removed@gmail.com'
app.config['MAIL_PASSWORD'] = 'removed'
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = True

# Initialize SQLAlchemy with app
db = SQLAlchemy(app)

# Models
roles_users = db.Table('roles_users',
    db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
    db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))

class Role(db.Model, RoleMixin):
    id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.String(80), unique=True)
    description = db.Column(db.String(255))

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(255), unique=True)
    password = db.Column(db.String(255))
    active = db.Column(db.Boolean())
    confirmed_at = db.Column(db.DateTime())
    roles = db.relationship('Role', secondary=roles_users, backref=db.backref('users', lazy='dynamic'))
    fs_uniquifier = db.Column(db.String(255), unique=True, nullable=False)


category_word_table = db.Table('category_word',
    db.Column('word_id', db.Integer, db.ForeignKey('dictionary.id'), primary_key=True),
    db.Column('category_id', db.Integer, db.ForeignKey('category.id'), primary_key=True))

class Category(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False, unique=True)
    words = db.relationship('Dictionary', secondary=category_word_table, backref='categories')

class Dictionary(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    word = db.Column(db.String(255))
    definition = db.Column(db.Text)


class UserInteraction(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    word_id = db.Column(db.Integer, db.ForeignKey('dictionary.id'))
    transcribed_word = db.Column(db.String(255))
    is_correct = db.Column(db.Boolean)

    user = db.relationship('User', backref=db.backref('interactions', lazy='dynamic'))
    word = db.relationship('Dictionary', backref=db.backref('interactions', lazy='dynamic'))


class ExceptionWord(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    word = db.Column(db.String(255), unique=True)
    transcription = db.Column(db.String(255))

def init_db(app):
    Migrate(app, db)
    with app.app_context():
        db.create_all()

# Blueprints
from blueprints.index import index_blueprint
from blueprints.pronounce import pronounce_blueprint
from blueprints.how_it_works import how_it_works_blueprint
from blueprints.dashboard import dashboard_blueprint
from blueprints.upload import upload_blueprint
from blueprints.categories import categories_blueprint
from blueprints.exceptions import exceptions_blueprint
from blueprints.routes import routes_blueprint

app.register_blueprint(index_blueprint)
app.register_blueprint(pronounce_blueprint, url_prefix='/pronounce')
app.register_blueprint(how_it_works_blueprint, url_prefix='/how_it_works')
app.register_blueprint(dashboard_blueprint, url_prefix='/dashboard')
app.register_blueprint(upload_blueprint, url_prefix='/upload')
app.register_blueprint(categories_blueprint, url_prefix='/categories')
app.register_blueprint(exceptions_blueprint, url_prefix='/exceptions')
app.register_blueprint(routes_blueprint)

# Flask-Security setup
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)

# Initialize database
init_db(app)

# Setup Flask-Mail
mail = Mail(app)

if __name__ == '__main__':
    app.run()

since I've rearranged things i now sometimes get this error instead, and the site seems a bit slower now. sqlalchemy.exc.OperationalError: (MySQLdb.OperationalError) (4031, 'The client was disconnected by the server because of inactivity. See wait_timeout and interactive_timeout for configuring this behavior.')

I was getting this error exclusively when the models where in their own py file. (MySQLdb.OperationalError: (2013, 'Lost connection to MySQL server during query')).

This all happens within seconds after refreshing. The errors go away if i hit refresh 3 or 4 times. Then the site tends to work well until i stop using it for a few minutes, and the issue returns when i return. I am at a loss here.

See https://help.pythonanywhere.com/pages/UsingSQLAlchemywithMySQL/

Thanks for all the help. The problem is me making changes on the server. Every time i make any change to the code and refresh, the connection to the db freaks out for a few refreshes and then it works again. Since all i ever do is update the code and check the site i assumed it was broken. I feel dumb, but i thought it was important to come back here and possibly help someone like me in the future.