我正在使用Python,Flask和SQLAlchemy。 我在构建应用程序时一直在使用本地数据库,并且使用以下代码工作正常:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config[
'SQLALCHEMY_DATABASE_URI'] = \
'mysql+pymysql://<username>:<password>@localhost/<DBName>'
db = SQLAlchemy(app)
现在,我尝试使用Python包sshtunnel将此代码连接到远程数据库。以下是此代码的样子:
from flask import Flask
from sshtunnel import SSHTunnelForwarder
from flask_sqlalchemy import SQLAlchemy
forwarding_server = SSHTunnelForwarder(
'1.2.3.4', #my host IP address
ssh_username="user",
ssh_password="password",
remote_bind_address=('127.0.0.1', 8080)
)
forwarding_server.start()
local_port = str(forwarding_server.local_bind_port)
app = Flask(__name__)
app.config[
'SQLALCHEMY_DATABASE_URI'] = \
'mysql+pymysql://<username>:<password>@127.0.0.1:' + local_port + '/<DBName>'
db = SQLAlchemy(app)
看起来像是连接,但是在启动我的烧瓶应用程序后,我立即收到以下错误:
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2013, 'Lost connection to MySQL server during query')
对此问题的任何见解都会有所帮助。提前谢谢!
答案 0 :(得分:2)
您可以在SQLALCHEMY_POOL_RECYCLE
的配置中将SQLALCHEMY_POOL_TIMEOUT
设置为小于Flask-SQLAlchemy
的值。查看文档的timeouts部分。
答案 1 :(得分:0)
我尝试的pool_recycle值小于wait_timeout(为mariadb数据库使用50),但是我不知道为什么它对我不起作用!在try中使用显式的pre_ping和会话回滚/关闭/除了对我不利的工作。我在下面使用此装饰器包装了所有功能,并解决了我的问题:
def manage_session(f):
def inner(*args, **kwargs):
# MANUAL PRE PING
try:
db.session.execute("SELECT 1;")
db.session.commit()
except:
db.session.rollback()
finally:
db.session.close()
# SESSION COMMIT, ROLLBACK, CLOSE
try:
res = f(*args, **kwargs)
db.session.commit()
return res
except Exception as e:
db.session.rollback()
raise e
# OR return traceback.format_exc()
finally:
db.session.close()
return inner
然后像下面这样修饰我的功能:
@manage_session
def my_function(*args, **kwargs):
return "result"