【问题标题】:Flask SQLAlchemy - 2013 Lost ConnectionFlask SQLAlchemy - 2013 失去连接
【发布时间】:2017-06-29 00:52:19
【问题描述】:

所以我正在尝试使用数据库和烧瓶动态构建网站。该网站目前按我希望的方式运行,但只运行了大约一分钟,我收到一条错误消息:

sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2013, 'Lost connection to MySQL server during query')

数据库包含我要为每一页抓取的 4 个条目,以及一个主页,我只从数据库中的每个条目中抓取 2 个条目。 在某个地方,它遇到了一个错误,它无法再访问数据库,因此不允许加载更多使用数据库的页面。

谁能帮我弄清楚为什么会发生这种情况?我对烧瓶和 sqlalchemy 很陌生

下面是我的代码:

数据库.py

​​>
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

app.py

​​>
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 -

【问题讨论】:

    标签: python mysql flask sqlalchemy flask-sqlalchemy


    【解决方案1】:

    根据thisthis 和互联网上许多其他文章的建议,使用以下装饰器包装我的所有功能帮助我解决了以 mariadb 作为后端数据库的“丢失连接”问题。请注意,下面的dbflask_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,但这对解决方案没有明显贡献。

    【讨论】:

      【解决方案2】:

      我遇到了类似的问题。这是我的解决方案:

      从数据库(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】:

      此问题与 sqlalchemy 或烧瓶无关。它实际上是在 mysql 服务器端。正在使用的服务器超时并断开与任何非本地连接的连接。

      切换到本地 sqlite 数据库为我解决了这个问题,直到我能够获得另一台服务器来托管 mysql 数据库,该服务器允许远程连接/在数据库的本地主机上托管站点。

      【讨论】:

        【解决方案4】:

        首先,为什么要在 app.py 和 Database.py 中两次实例化 Flask 对象?您的项目应该只实例化一个 Flask 对象。如果您想让您的 Flask 项目更加模块化,请在此处查看蓝图对象http://flask.pocoo.org/docs/0.12/blueprints/#blueprints

        现在,请尝试以下方法并注意我尚未对此进行测试,如果它不起作用,请告诉我:

        数据库.py

        ​​>
        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
        

        app.py

        ​​>
        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()
        

        【讨论】:

        • 我复制了更改,但是我收到了这个错误:Traceback (most recent call last): File "/home/devin-matte/Documents/Coralite/app.py", line 3, in &lt;module&gt; from Database import Kitchen File "/home/devin-matte/Documents/Coralite/Database.py", line 1, in &lt;module&gt; from app import db File "/home/devin-matte/Documents/Coralite/app.py", line 3, in &lt;module&gt; from Database import Kitchen ImportError: cannot import name 'Kitchen'
        • 因此将 Kitchens 类移动到 app.py 修复了该错误。但现在我仍然收到与发布初始帖子之前相同的错误。
        • 我明白了,这是循环导入。在实例化 SQLAlchemy 对象后尝试导入 Kitchen 对象。再次道歉,我无法在写作之前对此进行测试,我只是想提供帮助。在 db = SQLAlchemy(app) 之后,执行 from Database import Kitchen 并查看结果。
        • db = SQLAlchemy(app) 之后导入对错误没有帮助。也不要担心不测试,感谢帮助
        • 好的,如上所述,发生这种情况的原因是由于循环导入。现在,我通过导入文件并引用 Kitchen 对象来修复它,如下所示:import Database。此导入语句将与我的第一个响应位于同一位置,在 db = SQLAlchemy(app) 之前。唯一的问题是你必须做Database.Kitchen 任何你想要访问Kitchen 对象的事情。试试这个,让我知道!
        猜你喜欢
        • 1970-01-01
        • 2016-04-22
        • 2019-12-13
        • 2013-04-03
        • 2015-07-28
        • 1970-01-01
        • 2019-12-28
        • 2015-11-17
        • 2021-08-30
        相关资源
        最近更新 更多