Dear all. I am looking for some support here. I am enthusiast coder developing a Python Flask app for my sports group. By no means am I a developer. The app runs mostly successfully by now.
I use SQLAlchemy and connect to the MySQL DB on Pythonanywhere.
app = Flask(__name__)
app.config['SECRET_KEY'] = 'a_very_secret_key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+mysqlconnector://USER:PASSWORDv@USER.mysql.eu.pythonanywhere-services.com/DB$DB'
app.config['SQLALCHEMY_POOL_RECYCLE'] = 280
db = SQLAlchemy(app)
migrate = Migrate(app, db)
After a few minutes on first visit to the website (it queries the Database right away) the internal server error is shown. I assume it's because of issues with the database connection timeout.
mysql.connector.errors.OperationalError: MySQL Connection not available.
**NO MATCH**
The above exception was the direct cause of the following exception:
**NO MATCH**
Traceback (most recent call last):
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/flask/app.py", line 1455, in wsgi_app
response = self.full_dispatch_request()
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/flask/app.py", line 869, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/flask/app.py", line 867, in full_dispatch_request
rv = self.dispatch_request()
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/flask/app.py", line 852, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/flask_login/utils.py", line 284, in decorated_view
elif not current_user.is_authenticated:
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/werkzeug/local.py", line 311, in __get__
obj = instance._get_current_object()
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/werkzeug/local.py", line 515, in _get_current_object
return get_name(local())
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/flask_login/utils.py", line 25, in <lambda>
current_user = LocalProxy(lambda: _get_user())
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/flask_login/utils.py", line 372, in _get_user
current_app.login_manager._load_user()
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/flask_login/login_manager.py", line 364, in _load_user
user = self._user_callback(user_id)
File "/home/padel/app.py", line 157, in load_user
return Player.query.get(int(user_id))
File "<string>", line 2, in get
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/sqlalchemy/util/deprecations.py", line 386, in warned
return fn(*args, **kwargs) # type: ignore[no-any-return]
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/sqlalchemy/orm/query.py", line 1136, in get
return self._get_impl(ident, loading.load_on_pk_identity)
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/sqlalchemy/orm/query.py", line 1145, in _get_impl
return self.session._get_impl(
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 3831, in _get_impl
return db_load_fn(
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/sqlalchemy/orm/loading.py", line 690, in load_on_pk_identity
session.execute(
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 2306, in execute
return self._execute_internal(
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 2188, in _execute_internal
result: Result[Any] = compile_state_cls.orm_execute_statement(
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/sqlalchemy/orm/context.py", line 293, in orm_execute_statement
result = conn.execute(
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1416, in execute
return meth(
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/sqlalchemy/sql/elements.py", line 516, in _execute_on_connection
return connection._execute_clauseelement(
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1639, in _execute_clauseelement
ret = self._execute_context(
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1820, in _execute_context
self._handle_dbapi_exception(
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 2343, in _handle_dbapi_exception
raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1814, in _execute_context
context = constructor(
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/sqlalchemy/engine/default.py", line 1399, in _init_compiled
self.cursor = self.create_cursor()
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/sqlalchemy/engine/default.py", line 1723, in create_cursor
return self.create_default_cursor()
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/sqlalchemy/engine/default.py", line 1729, in create_default_cursor
return self._dbapi_connection.cursor()
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 1491, in cursor
return self.dbapi_connection.cursor(*args, **kwargs)
File "/home/padel/.virtualenvs/venv/lib/python3.10/site-packages/mysql/connector/connection_cext.py", line 706, in cursor
raise OperationalError("MySQL Connection not available.")
sqlalchemy.exc.OperationalError: (mysql.connector.errors.OperationalError) MySQL Connection not available.
[SQL: SELECT player.id AS player_id, player.name AS player_name, player.skill_level AS player_skill_level, player.match_id AS player_match_id, player.paid AS player_paid, player.position AS player_position, player.is_admin AS player_is_admin, player.on_waitlist AS player_on_waitlist, player.regular AS player_regular, player.signup_week AS player_signup_week
FROM player
WHERE player.id = %(pk_1)s]
[parameters: [{'pk_1': 35}]]
This is the route that I assume causes the error right away:
@app.route('/', methods=['GET', 'POST'])
def index():
form = SignupForm()
current_week_number = date.today().isocalendar()[1]
players_count = len(Player.query.filter_by(signup_week=current_week_number).all())
courts_config = Configuration.query.filter_by(key="available_courts").first()
if courts_config:
max_players = int(courts_config.value) * 4
else:
max_players = 0
is_on_waitlist = players_count >= max_players
if form.validate_on_submit():
# Check if a player with the given name exists in the database
player_in_db = Player.query.filter_by(name=form.name.data).first()
if player_in_db and player_in_db.regular:
# If they are a regular, check if they are signed up for the current week
existing_signup = Player.query.filter_by(name=form.name.data, signup_week=current_week_number).first()
if existing_signup:
# If signed up, remove their signup_week and display an opt-out message
existing_signup.signup_week = None
db.session.commit()
flash(f"{form.name.data} has opted out for this week. Thanks! You will be signed up automatically next week", 'danger')
else:
# Check if a player with the same name is already signed up for the current week
existing_player = Player.query.filter_by(name=form.name.data, signup_week=current_week_number).first()
if existing_player:
flash(f"{form.name.data} is already signed up for the current week. If it was not you, please add your initial to your name", 'danger')
else:
player = Player(name=form.name.data, skill_level=form.skill_level.data,
signup_week=current_week_number, on_waitlist=is_on_waitlist)
db.session.add(player)
db.session.commit()
flash(f"Thank you for signing up, {form.name.data}!", 'success')
return redirect(url_for('index'))
return render_template('signup.html', form=form, courts=max_players // 4,
players_count=players_count, max_players=max_players, is_on_waitlist=is_on_waitlist)
What can I do to be sure that the application loads right away when a player visits the site? I assume it's about closing the DB connections once commits have been made but I struggle to wrap my head around the details. Unless it's something else entirely.
Any help or directions are greatly appreciated.
Thanks!