Как подключиться к MySQL с помощью приложения Flask на Heroku с помощью SQLAlchemy

На локальной машине с использованием локальной базы данных MySQL все идет нормально. Вот мой файл приложения __init__.py:

#rootfolder/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import os

ON_HEROKU = 'ON_HEROKU' in os.environ

if ON_HEROKU:
    DB_URL = os.environ.get('CLEARDB_DATABASE_URL')
else:
    from dotenv import load_dotenv
    load_dotenv()
    DB_URL = os.getenv('MYSQL_URL')

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = DB_URL
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

from projectname.Controller.root import root
from projectname.Controller.user_controller import user_routes # This imports Model too

app.register_blueprint(root)
app.register_blueprint(user_routes)

db.create_all()

user_routes Blueprint также импортирует классы модели. Я вижу созданные таблицы в своей локальной базе данных, так что логика выглядит нормально.

Распечатал 'HELLO' и DB_URL внутри условия if ON_HEROKU: для проверки URL в облаке:

if ON_HEROKU:
  DB_URL = os.environ.get('CLEARDB_DATABASE_URL')
  print('HELLO')
  print(DB_URL)

Я вижу, как они просматривают логи героку:

.
.
app[web.1]: HELLO
app[web.1]: mysql://*********:*******@us-cdbr-iron-east-05.cleardb.net/heroku_c52490fb3111cda?reconnect=true
.
.

Действительно, у меня есть установленная ClearDB на героку с этим URL-адресом в качестве переменной конфигурации:

введите здесь описание изображения

Мне также удалось подключиться к этой базе данных heroku с помощью HeidiSQL, и созданный мной URL-адрес heroku. Так что все должно быть на месте.

Комментируя функцию db.create_all(), развернутое приложение heroku не выдает ошибок, и я вижу базовое сообщение json, следующее за моим корневым маршрутом. Однако, добавляя db.create_all() обратно, я получаю следующую ошибку журнала:

app[web.1]:     db.create_all()
app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 1033, in create_all
  .
  .
  .
app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/sqlalchemy/dialects/mysql/mysqldb.py", line 118, in dbapi
app[web.1]:     return __import__("MySQLdb")
app[web.1]: ModuleNotFoundError: No module named 'MySQLdb'

У меня были подобные ошибки локально, поэтому я попытался изменить URL-адрес, который дал мне геройку, с именем драйвера mysql+pymysql:// и добавив PyMySQL==0.9.3 к моему requirements.txt (я не уверен, что геройку проверяет это).

введите здесь описание изображения

Не хватило ошибки теперь:

app[web.1]:     db.create_all()
app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 1033, in create_all
  .
  .
  .
app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/pymysql/__init__.py", line 94, in Connect
app[web.1]:     return Connection(*args, **kwargs)
app[web.1]: TypeError: __init__() got an unexpected keyword argument 'reconnect'

Мой Procfile выглядит так: web gunicorn run:app, так как run.py запускает все приложение.

Что мне здесь не хватает?


person MattSom    schedule 21.10.2019    source источник
comment
Привет! Это похоже на дубликат stackoverflow.com/questions/45308110/ Если вы удалите ?reconnect=True, устранит ли это проблему?   -  person Jose Salvatierra    schedule 21.10.2019
comment
@JoseSalvatierra Да, спасибо! Они также говорят о другой проблеме, вызванной удалением параметра ?reconnect=true, который теряет созданное соединение после некоторых запросов. Я собираюсь проверить это, но пока это работает. :)   -  person MattSom    schedule 21.10.2019
comment
Да, я считаю, что вам придется использовать пул соединений SQLAlchemy, чтобы решить эту проблему. Он может воссоздавать разорванные соединения, не восстанавливая их.   -  person Jose Salvatierra    schedule 21.10.2019
comment
@JoseSalvatierra Кстати, есть ли какое-то объяснение, почему ?reconnect=True нужно удалить? Мое соединение действительно теперь имеет проблемы с повторным подключением, так что это похоже на отказ от вполне разумной функции. Почему пул соединений SQLAlchemy лучше, чем реализация использования этого параметра?   -  person MattSom    schedule 03.11.2019
comment
Я не знаком с пакетом, но кажется, что MySQLdb не поддерживает этот аргумент.   -  person Jose Salvatierra    schedule 04.11.2019