所以我正在尝试使用数据库和烧瓶动态构建网站。该网站现在正如我所希望的那样,但只有大约一分钟我收到错误消息说:
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2013, 'Lost connection to MySQL server during query')
数据库包含我想为每个页面抓取的4个条目,以及一个主页面,其中我只从数据库中的每个条目中获取2个条目。 在某个地方,它会遇到一个错误,它无法再访问数据库,因此不允许再加载使用该数据库的页面。
任何人都可以帮我弄清楚为什么会这样吗?我对于烧瓶和sqlalchemy来说很新鲜
以下是我的代码:
from flask import Flask
from flask import render_template
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://databaseaddress'
db = SQLAlchemy(app)
class Kitchen(db.Model):
__tablename__ = 'kitchens'
id = db.Column('id', db.Integer, primary_key=True)
description = db.Column('description')
galleryId = db.Column('galleryId')
cpo = db.Column('cpo')
def __init__(self, description, galleryId, cpo):
self.description = description
self.galleryId = galleryId
self.cpo = cpo
def __repr__(self):
return '<Gallery %r>' % self.description
def get_description(self):
return self.description
def get_galleryId(self):
return self.galleryId
def get_cpo(self):
return self.cpo
from flask import Flask
from flask import render_template
from Database import Kitchen
app = Flask(__name__)
@app.route('/')
@app.route('/index')
def main():
return render_template('index.html')
@app.route('/kitchens', methods=['GET'], defaults={'n': 0})
@app.route('/kitchens/<n>', methods=['GET'])
def kitchens(n):
row = Kitchen.query.count()
if int(n) is 0:
description = []
for num in range(1, row+1):
data = Kitchen.query.filter_by(id=num).first()
description.append(Kitchen.get_description(data))
return render_template('Gallery Directory.html', portfolio='Kitchens', row=row, description=description)
elif int(n) >= 1:
data = Kitchen.query.filter_by(id=n).first()
description = Kitchen.get_description(data)
galleryId = Kitchen.get_galleryId(data)
cpo = Kitchen.get_cpo(data)
return render_template('Gallery Basic.html', portfolio='Kitchens', description=description, id=int(n),
galleryId=galleryId, cpo=cpo, row=row)
if __name__ == "__main__":
app.run()
[2017-02-10 10:17:31,776] ERROR in app: Exception on /kitchens/ 1 [GET]
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/engine/base.py", line 1182, in _execute_context
context)
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/engine/default.py", line 470, in do_execute
cursor.execute(statement, parameters)
File "/home/devin-matte/.local/lib/python3.5/site-packages/pymysql/cursors.py", line 166, in execute
result = self._query(query)
File "/home/devin-matte/.local/lib/python3.5/site-packages/pymysql/cursors.py", line 322, in _query
conn.query(q)
File "/home/devin-matte/.local/lib/python3.5/site-packages/pymysql/connections.py", line 835, in query
self._affected_rows = self._read_query_result(unbuffered=unbuffered)
File "/home/devin-matte/.local/lib/python3.5/site-packages/pymysql/connections.py", line 1019, in _read_query_result
result.read()
File "/home/devin-matte/.local/lib/python3.5/site-packages/pymysql/connections.py", line 1302, in read
first_packet = self.connection._read_packet()
File "/home/devin-matte/.local/lib/python3.5/site-packages/pymysql/connections.py", line 961, in _read_packet
packet_header = self._read_bytes(4)
File "/home/devin-matte/.local/lib/python3.5/site-packages/pymysql/connections.py", line 998, in _read_bytes
2013, "Lost connection to MySQL server during query")
pymysql.err.OperationalError: (2013, 'Lost connection to MySQL server during query')
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/devin-matte/.local/lib/python3.5/site-packages/flask/app.py", line 1988, in wsgi_app
response = self.full_dispatch_request()
File "/home/devin-matte/.local/lib/python3.5/site-packages/flask/app.py", line 1641, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/devin-matte/.local/lib/python3.5/site-packages/flask/app.py", line 1544, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/devin-matte/.local/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/home/devin-matte/.local/lib/python3.5/site-packages/flask/app.py", line 1639, in full_dispatch_request
rv = self.dispatch_request()
File "/home/devin-matte/.local/lib/python3.5/site-packages/flask/app.py", line 1625, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/devin-matte/Documents/Coralite/Coralite.py", line 18, in kitchens
row = Kitchen.query.count()
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/orm/query.py", line 3024, in count
return self.from_self(col).scalar()
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/orm/query.py", line 2778, in scalar
ret = self.one()
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/orm/query.py", line 2749, in one
ret = self.one_or_none()
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/orm/query.py", line 2719, in one_or_none
ret = list(self)
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/orm/query.py", line 2790, in __iter__
return self._execute_and_instances(context)
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/orm/query.py", line 2813, in _execute_and_instances
result = conn.execute(querycontext.statement, self._params)
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/engine/base.py", line 945, in execute
return meth(self, multiparams, params)
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/sql/elements.py", line 263, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/engine/base.py", line 1053, in _execute_clauseelement
compiled_sql, distilled_params
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/engine/base.py", line 1189, in _execute_context
context)
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/engine/base.py", line 1393, in _handle_dbapi_exception
exc_info
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/util/compat.py", line 203, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/util/compat.py", line 186, in reraise
raise value.with_traceback(tb)
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/engine/base.py", line 1182, in _execute_context
context)
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/engine/default.py", line 470, in do_execute
cursor.execute(statement, parameters)
File "/home/devin-matte/.local/lib/python3.5/site-packages/pymysql/cursors.py", line 166, in execute
result = self._query(query)
File "/home/devin-matte/.local/lib/python3.5/site-packages/pymysql/cursors.py", line 322, in _query
conn.query(q)
File "/home/devin-matte/.local/lib/python3.5/site-packages/pymysql/connections.py", line 835, in query
self._affected_rows = self._read_query_result(unbuffered=unbuffered)
File "/home/devin-matte/.local/lib/python3.5/site-packages/pymysql/connections.py", line 1019, in _read_query_result
result.read()
File "/home/devin-matte/.local/lib/python3.5/site-packages/pymysql/connections.py", line 1302, in read
first_packet = self.connection._read_packet()
File "/home/devin-matte/.local/lib/python3.5/site-packages/pymysql/connections.py", line 961, in _read_packet
packet_header = self._read_bytes(4)
File "/home/devin-matte/.local/lib/python3.5/site-packages/pymysql/connections.py", line 998, in _read_bytes
2013, "Lost connection to MySQL server during query")
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2013, 'Lost connection to MySQL server during query') [SQL: 'SELECT count(*) AS count_1 \nFROM (SELECT kitchens.id AS kitchens_id, kitchens.description AS kitchens_description, kitchens.`galleryId` AS `kitchens_galleryId`, kitchens.cpo AS kitchens_cpo \nFROM kitchens) AS anon_1']
127.0.0.1 - - [10/Feb/2017 10:17:31] "GET /kitchens/%201 HTTP/1.1" 500 -
答案 0 :(得分:0)
首先,为什么要在app.py和Database.py中两次实例化Flask对象?您的项目应该只实例化一个Flask对象。如果您想让Flask项目更加模块化,请在此处查看Blueprint对象http://flask.pocoo.org/docs/0.12/blueprints/#blueprints。
现在,请尝试以下操作并注意我没有对此进行测试,如果它没有工作让我知道:
from flask import Flask
from flask import render_template
from app import db
class Kitchen(db.Model):
__tablename__ = 'kitchens'
id = db.Column('id', db.Integer, primary_key=True)
description = db.Column('description')
galleryId = db.Column('galleryId')
cpo = db.Column('cpo')
def __init__(self, description, galleryId, cpo):
self.description = description
self.galleryId = galleryId
self.cpo = cpo
def __repr__(self):
return '<Gallery %r>' % self.description
def get_description(self):
return self.description
def get_galleryId(self):
return self.galleryId
def get_cpo(self):
return self.cpo
from flask import Flask
from flask import render_template
from Database import Kitchen
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://databaseaddress'
db = SQLAlchemy(app)
@app.route('/')
@app.route('/index')
def main():
return render_template('index.html')
@app.route('/kitchens', methods=['GET'], defaults={'n': 0})
@app.route('/kitchens/<n>', methods=['GET'])
def kitchens(n):
row = Kitchen.query.count()
if int(n) is 0:
description = []
for num in range(1, row+1):
data = Kitchen.query.filter_by(id=num).first()
description.append(Kitchen.get_description(data))
return render_template('Gallery Directory.html', portfolio='Kitchens', row=row, description=description)
elif int(n) >= 1:
data = Kitchen.query.filter_by(id=n).first()
description = Kitchen.get_description(data)
galleryId = Kitchen.get_galleryId(data)
cpo = Kitchen.get_cpo(data)
return render_template('Gallery Basic.html', portfolio='Kitchens', description=description, id=int(n),
galleryId=galleryId, cpo=cpo, row=row)
if __name__ == "__main__":
db.create_all()
app.run()
答案 1 :(得分:0)
此问题不适用于sqlalchemy或flask。它实际上是在mysql服务器端。正在使用的服务器是超时并断开与非本地主机的任何连接。
切换到本地sqlite数据库解决了这个问题,直到我能够获得一个不同的服务器来托管mysql数据库,允许远程连接/托管数据库的localhost上的站点。
答案 2 :(得分:0)
我遇到了类似的问题。这是我的解决方案:
从DB(MariaDB / MySQL)获取wait_timeout
SHOW GLOBAL VARIABLES LIKE "wait_timeout";
在Flask代码中设置SQLALCHEMY_POOL_RECYCLE:
app = Flask(__name__)
app.config['SQLALCHEMY_POOL_RECYCLE'] = <db_wait_timeout> - 1
答案 3 :(得分:0)
根据this,this和互联网上许多其他文章的建议,使用以下装饰器包装我的所有功能,帮助我解决了mariadb作为后端数据库的“丢失连接”问题。请注意,下面的db
是flask_sqlalchemy.SQLAlchemy
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
我还在Flask SQLAlchemy配置中添加了50秒的pool_recycle,但这显然没有对解决方案有所帮助。