sqlalchemy不关闭mysql数据库连接

amrnrhlw  于 2021-06-18  发布在  Mysql
关注(0)|答案(2)|浏览(439)

我有一个flask应用程序,使用flask sqlalchemy和一个mysql数据库,其中db的定义如下: db.py :

from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
``` `main.py` :

from db import db
app = Flask(name)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://" +
DB_USERNAME + ":" + DB_PASSWORD + "@" + DB_HOST + "/" + DB_DATABASE
db.init_app(app)

@app.teardown_appcontext
def teardown_db(error):
db.session.close()
db.engine.dispose()
``` user.py :

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)

我使用模型查询我的数据库 db.engine.execute() 在需要的地方编写原始sql查询,或者使用集成的flask sqlalchemy api来读取数据,例如 User.query.filter_by().all() .
我使用以下方法将新数据写入数据库:

new_user_entry = User(username = "abc", email = "abc@example.com")
db.session.add(new_user_entry)
db.session.commit()

我正在使用 show processlist 我注意到,对于每一个请求,数据库连接不断增加2。数据库连接似乎只有在我停止flask进程时才会重置。随着时间的推移,mysql服务器会抛出以下错误:

`sqlalchemy.exc.TimeoutError: QueuePool limit of size 10 overflow 10 reached, connection timed out, timeout 30 (Background on this error at: http://sqlalche.me/e/3o7r)`

我使用gunicorn和gevent/eventlet为应用程序提供服务,其中包含2个工作进程。我用Python。
我是不是漏了什么?我试图结束db会话并处理引擎,但这似乎不起作用。

inkz8wg9

inkz8wg91#

我终于找到了解决上述问题的办法。
我使用了这里定义的声明性模型,而不是遵循这里给出的flask sqlalchemy的快速启动文档。
更改的文件如下: db.py :

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine(DB_URI, convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()

def init_db():
    import user
    Base.metadata.create_all(bind=engine)
``` `main.py` :

from db import init_db, db_session

init_db()

@app.teardown_appcontext
def shutdown_session(exception=None):
db_session.remove()
``` user.py :

from sqlalchemy import Column, Integer, String
from data_models.db import Base
class User(Base):
    id = db.Column(Integer, primary_key=True)
    username = db.Column(String(80), unique=True, nullable=False)
    email = db.Column(String(120), unique=True, nullable=False)

要查询记录,我们可以使用 User.query.filter_by().all() 或者 db_engine.execute() .
要将新数据写入数据库,可以使用以下方法:

new_user_entry = User(username = "abc", email = "abc@example.com")
db_session.add(new_user_entry)
db_session.commit()
v9tzhpje

v9tzhpje2#

如果我们需要在创建新的子进程之前关闭会话(建议这样做),我们应该使用以下方法:

db.session.remove()
db.engine.dispose()

喜欢

from multiprocessing import Process
from app import db

@app.route('/process/start/', methods = ["GET"])
def process_start():
    db.session.remove()
    db.engine.dispose()
    p = Process(target = long_task)
    p.start()
    return 'started the long task'

def long_task():
    '''
    do long task
    '''

相关问题