lor*_*das 2 python mysql sqlalchemy flask flask-sqlalchemy
我有一个 Flask 应用程序,使用 Flask-SQLAlchemy 和 MySQL 数据库,其中数据库定义如下:
db.py
:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
Run Code Online (Sandbox Code Playgroud)
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()
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
我使用模型查询数据库,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()
Run Code Online (Sandbox Code Playgroud)
我正在使用 MySQL 服务器进行监控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)`
Run Code Online (Sandbox Code Playgroud)
我使用 Gunicorn 和 gevent/eventlet 以及 2 个工作进程来为应用程序提供服务。我用的是python3。
我在这里错过了什么吗?我尝试结束数据库会话并处置引擎,但这似乎不起作用。
我终于找到了解决上述问题的方法。
我使用了此处定义的声明性模型,而不是遵循此处给出的 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)
Run Code Online (Sandbox Code Playgroud)
main.py
:
from db import init_db, db_session
init_db()
@app.teardown_appcontext
def shutdown_session(exception=None):
db_session.remove()
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
要查询记录,我们可以使用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()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8069 次 |
最近记录: |